From ba0855705e780ccf20744acdccd6d9ad9eee9326 Mon Sep 17 00:00:00 2001 From: Nuno Campos Date: Tue, 25 Feb 2025 08:38:40 -0800 Subject: [PATCH] Add prompts folder - hurl.md is used when generating README journeys --- prompts/hurl.md | 817 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 817 insertions(+) create mode 100644 prompts/hurl.md diff --git a/prompts/hurl.md b/prompts/hurl.md new file mode 100644 index 0000000..8281e9f --- /dev/null +++ b/prompts/hurl.md @@ -0,0 +1,817 @@ +# Hurl Manual + +## Name + +hurl - run and test HTTP requests. + +## Synopsis + +**hurl** [options] [FILE...] + +## Description + +**Hurl** is a command line tool that runs HTTP requests defined in a simple plain text format. + +It can chain requests, capture values and evaluate queries on headers and body response. Hurl is very versatile, it can be used for fetching data and testing HTTP sessions: HTML content, REST / SOAP / GraphQL APIs, or any other XML / JSON based APIs. + +```shell +$ hurl session.hurl +``` + +If no input files are specified, input is read from stdin. + +```shell +$ echo GET http://httpbin.org/get | hurl + { + "args": {}, + "headers": { + "Accept": "*/*", + "Accept-Encoding": "gzip", + "Content-Length": "0", + "Host": "httpbin.org", + "User-Agent": "hurl/0.99.10", + "X-Amzn-Trace-Id": "Root=1-5eedf4c7-520814d64e2f9249ea44e0" + }, + "origin": "1.2.3.4", + "url": "http://httpbin.org/get" + } +``` + +Hurl can take files as input, or directories. In the latter case, Hurl will search files with `.hurl` extension recursively. + +Output goes to stdout by default. To have output go to a file, use the [`-o, --output`](#output) option: + +```shell +$ hurl -o output input.hurl +``` + +By default, Hurl executes all HTTP requests and outputs the response body of the last HTTP call. + +To have a test oriented output, you can use [`--test`](#test) option: + +```shell +$ hurl --test *.hurl +``` + +## Hurl File Format + +The Hurl file format is fully documented in [https://hurl.dev/docs/hurl-file.html](https://hurl.dev/docs/hurl-file.html) + +It consists of one or several HTTP requests + +```hurl +GET http://example.org/endpoint1 +GET http://example.org/endpoint2 +``` + +### Capturing values + +A value from an HTTP response can be-reused for successive HTTP requests. + +A typical example occurs with CSRF tokens. + +```hurl +GET https://example.org +HTTP 200 +# Capture the CSRF token value from html body. +[Captures] +csrf_token: xpath "normalize-space(//meta[@name='_csrf_token']/@content)" + +# Do the login ! +POST https://example.org/login?user=toto&password=1234 +X-CSRF-TOKEN: {{csrf_token}} +``` + +More information on captures can be found here [https://hurl.dev/docs/capturing-response.html](https://hurl.dev/docs/capturing-response.html) + +### Asserts + +The HTTP response defined in the Hurl file are used to make asserts. Responses are optional. + +At the minimum, response includes assert on the HTTP status code. + +```hurl +GET http://example.org +HTTP 301 +``` + +It can also include asserts on the response headers + +```hurl +GET http://example.org +HTTP 301 +Location: http://www.example.org +``` + +Explicit asserts can be included by combining a query and a predicate + +```hurl +GET http://example.org +HTTP 301 +[Asserts] +xpath "string(//title)" == "301 Moved" +``` + +With the addition of asserts, Hurl can be used as a testing tool to run scenarios. + +More information on asserts can be found here [https://hurl.dev/docs/asserting-response.html](https://hurl.dev/docs/asserting-response.html) + +## Hurl Request Format + +### Definition + +Request describes an HTTP request: a mandatory [method] and [URL], followed by optional [headers]. + +Then, [options], [query parameters], [form parameters], [multipart form data], [cookies], and [basic authentication] +can be used to configure the HTTP request. + +Finally, an optional [body] can be used to configure the HTTP request body. + +### Example + +```hurl +GET https://example.org/api/dogs?id=4567 +User-Agent: My User Agent +Content-Type: application/json +[BasicAuth] +alice: secret +``` + +### Structure + +
+
+
+
+ PUT https://sample.net +
+
+ accept: */*
x-powered-by: Express
user-agent: Test +
+
+ [Options]
... +
+
+ [QueryStringParams]
... +
+
+ [FormParams]
... +
+
+ [BasicAuth]
... +
+
+ [Cookies]
... +
+
+ ... +
+
+ ... +
+
+ {
+   "type": "FOO",
+   "value": 356789,
+   "ordered": true,
+   "index": 10
+ } +
+
+
+
+ Method and URL (mandatory) +
+
+
HTTP request headers (optional) +
+
+
+
+
+
+
+
+
+ Options, query strings, form params, cookies, authentication ...
(optional sections, unordered) +
+
+
+
+
+
+
+
+
+
+
+ HTTP request body (optional) +
+
+
+
+ +[Headers], if present, follow directly after the [method] and [URL]. This allows Hurl format to 'look like' the real HTTP format. +Contrary to HTTP headers, other parameters are defined in sections (`[Cookies]`, `[QueryStringParams]`, `[FormParams]` etc...) +These sections are not ordered and can be mixed in any way: + +```hurl +GET https://example.org/api/dogs +User-Agent: My User Agent +[QueryStringParams] +id: 4567 +order: newest +[BasicAuth] +alice: secret +``` + +```hurl +GET https://example.org/api/dogs +User-Agent: My User Agent +[BasicAuth] +alice: secret +[QueryStringParams] +id: 4567 +order: newest +``` + +The last optional part of a request configuration is the request [body]. Request body must be the last parameter of a request +(after [headers] and request sections). Like headers, body have no explicit marker: + +```hurl +POST https://example.org/api/dogs?id=4567 +User-Agent: My User Agent +{ + "name": "Ralphy" +} +``` + +### Description + +#### Method + +Mandatory HTTP request method, usually one of `GET`, `HEAD`, `POST`, `PUT`, `DELETE`, `CONNECT`, `OPTIONS`, +`TRACE` and `PATCH`. + +> Other methods can be used like `QUERY` with the constraint of using only uppercase chars. + +#### URL + +Mandatory HTTP request URL. + +URL can contain query parameters, even if using a [query parameters section] is preferred. + +```hurl +# A request with URL containing query parameters. +GET https://example.org/forum/questions/?search=Install%20Linux&order=newest + +# A request with query parameters section, equivalent to the first request. +GET https://example.org/forum/questions/ +[QueryStringParams] +search: Install Linux +order: newest +``` + +> Query parameters in query parameter section are not URL encoded. + +When query parameters are present in the URL and in a query parameters section, the resulting request will +have both parameters. + +#### Headers + +Optional list of HTTP request headers. + +A header consists of a name, followed by a `:` and a value. + +```hurl +GET https://example.org/news +User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:70.0) Gecko/20100101 Firefox/70.0 +Accept: */* +Accept-Language: en-US,en;q=0.5 +Accept-Encoding: gzip, deflate, br +Connection: keep-alive +``` + +> Headers directly follow URL, without any section name, contrary to query parameters, form parameters +> or cookies + +Note that a header usually doesn't start with double quotes. If a header value starts with double quotes, double +quotes will be part of the header value: + +```hurl +PATCH https://example.org/file.txt +If-Match: "e0023aa4e" +``` + +`If-Match` request header will be sent will the following value `"e0023aa4e"` (started and ended with double quotes). + +Headers must follow directly after the [method] and [URL]. + +#### Options + +Options used to execute this request. + +Options such as [`--location`], [`--verbose`], [`--insecure`] can be used at the command line and applied to every +request of an Hurl file. An `[Options]` section can be used to apply option to only one request (without passing options +to the command line), while other requests are unaffected. + +```hurl +GET https://example.org +# An options section, each option is optional and applied only to this request... +[Options] +aws-sigv4: aws:amz:sts # generate AWS SigV4 Authorization header +cacert: /etc/cert.pem # custom certificate file +cert: /etc/client-cert.pem # client authentication certificate +key: /etc/client-cert.key # client authentication certificate key +compressed: true # request a compressed response +connect-timeout: 20s # connect timeout +delay: 3s # delay for this request (aka sleep) +http3: true # use HTTP/3 protocol version +insecure: true # allow insecure SSL connections and transfers +ipv6: true # use IPv6 addresses +limit-rate: 32000 # limit this request to the specidied speed (bytes/s) +location: true # follow redirection for this request +max-redirs: 10 # maximum number of redirections +output: out.html # dump the response to this file +path-as-is: true # do not handle sequences of /../ or /./ in URL path +retry: 10 # number of retry if HTTP/asserts errors +retry-interval: 500ms # interval between retry +skip: false # skip this request +unix-socket: sock # use Unix socket for transfer +user: bob:secret # use basic authentication +proxy: my.proxy:8012 # define proxy (host:port where host can be an IP address) +variable: country=Italy # define variable country +variable: planet=Earth # define variable planet +verbose: true # allow verbose output +very-verbose: true # allow more verbose output +``` + +> Variable defined in an `[Options]` section are defined also for the next entries. This is +> the exception, all other options are defined only for the current request. + +#### Query parameters + +Optional list of query parameters. + +A query parameter consists of a field, followed by a `:` and a value. The query parameters section starts with +`[QueryStringParams]`. Contrary to query parameters in the URL, each value in the query parameters section is not +URL encoded. + +```hurl +GET https://example.org/news +User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:70.0) Gecko/20100101 Firefox/70.0 +[QueryStringParams] +order: newest +search: {{custom-search}} +count: 100 +``` + +If there are any parameters in the URL, the resulted request will have both parameters. + +#### Form parameters + +A form parameters section can be used to send data, like [HTML form]. + +This section contains an optional list of key values, each key followed by a `:` and a value. Key values will be +encoded in key-value tuple separated by '&', with a '=' between the key and the value, and sent in the body request. +The content type of the request is `application/x-www-form-urlencoded`. The form parameters section starts +with `[FormParams]`. + +```hurl +POST https://example.org/contact +[FormParams] +default: false +token: {{token}} +email: john.doe@rookie.org +number: 33611223344 +``` + +Form parameters section can be seen as syntactic sugar over body section (values in form parameters section +are not URL encoded.). A [oneline string body] could be used instead of a forms parameters section. + +```hurl +# Run a POST request with form parameters section: +POST https://example.org/test +[FormParams] +name: John Doe +key1: value1 + +# Run the same POST request with a body section: +POST https://example.org/test +Content-Type: application/x-www-form-urlencoded +`name=John%20Doe&key1=value1` +``` + +When both [body section] and form parameters section are present, only the body section is taken into account. + +#### Multipart Form Data + +A multipart form data section can be used to send data, with key / value and file content +(see [multipart/form-data on MDN]). + +The form parameters section starts with `[MultipartFormData]`. + +```hurl +POST https://example.org/upload +[MultipartFormData] +field1: value1 +field2: file,example.txt; +# One can specify the file content type: +field3: file,example.zip; application/zip +``` + +Files are relative to the input Hurl file, and cannot contain implicit parent directory (`..`). You can use +[`--file-root` option] to specify the root directory of all file nodes. + +Content type can be specified or inferred based on the filename extension: + +- `.gif`: `image/gif`, +- `.jpg`: `image/jpeg`, +- `.jpeg`: `image/jpeg`, +- `.png`: `image/png`, +- `.svg`: `image/svg+xml`, +- `.txt`: `text/plain`, +- `.htm`: `text/html`, +- `.html`: `text/html`, +- `.pdf`: `application/pdf`, +- `.xml`: `application/xml` + +By default, content type is `application/octet-stream`. + +As an alternative to a `[MultipartFormData]` section, multipart forms can also be sent with a [multiline string body]: + +````hurl +POST https://example.org/upload +Content-Type: multipart/form-data; boundary="boundary" +``` +--boundary +Content-Disposition: form-data; name="key1" + +value1 +--boundary +Content-Disposition: form-data; name="upload1"; filename="data.txt" +Content-Type: text/plain + +Hello World! +--boundary +Content-Disposition: form-data; name="upload2"; filename="data.html" +Content-Type: text/html + +
Hello World!
+--boundary-- +``` +```` + +> When using a multiline string body to send a multipart form data, files content must be inlined in the Hurl file. + +#### Cookies + +Optional list of session cookies for this request. + +A cookie consists of a name, followed by a `:` and a value. Cookies are sent per request, and are not added to +the cookie storage session, contrary to a cookie set in a header response. (for instance `Set-Cookie: theme=light`). The +cookies section starts with `[Cookies]`. + +```hurl +GET https://example.org/index.html +[Cookies] +theme: light +sessionToken: abc123 +``` + +Cookies section can be seen as syntactic sugar over corresponding request header. + +```hurl +# Run a GET request with cookies section: +GET https://example.org/index.html +[Cookies] +theme: light +sessionToken: abc123 + +# Run the same GET request with a header: +GET https://example.org/index.html +Cookie: theme=light; sessionToken=abc123 +``` + +#### Basic Authentication + +A basic authentication section can be used to perform [basic authentication]. + +Username is followed by a `:` and a password. The basic authentication section starts with +`[BasicAuth]`. Username and password are _not_ base64 encoded. + +```hurl +# Perform basic authentication with login `bob` and password `secret`. +GET https://example.org/protected +[BasicAuth] +bob: secret +``` + +> Spaces surrounded username and password are trimmed. If you +> really want a space in your password (!!), you could use [Hurl unicode literals \u{20}]. + +This is equivalent (but simpler) to construct the request with a [Authorization] header: + +```hurl +# Authorization header value can be computed with `echo -n 'bob:secret' | base64` +GET https://example.org/protected +Authorization: Basic Ym9iOnNlY3JldA== +``` + +Basic authentication allows per request authentication. +If you want to add basic authentication to all the requests of a Hurl file +you can use [`-u/--user` option]. + +#### Body + +Optional HTTP body request. + +If the body of the request is a [JSON] string or a [XML] string, the value can be +directly inserted without any modification. For a text based body that is neither JSON nor XML, +one can use [multiline string body] that starts with ``` and ends +with ```. Multiline string body support "language hint" and can be used +to create [GraphQL queries]. + +For a precise byte control of the request body, [Base64] encoded string, [hexadecimal string] +or [included file] can be used to describe exactly the body byte content. + +> You can set a body request even with a `GET` body, even if this is not a common practice. + +The body section must be the last section of the request configuration. + +##### JSON body + +JSON request body is used to set a literal JSON as the request body. + +```hurl +# Create a new doggy thing with JSON body: +POST https://example.org/api/dogs +{ + "id": 0, + "name": "Frieda", + "picture": "images/scottish-terrier.jpeg", + "age": 3, + "breed": "Scottish Terrier", + "location": "Lisco, Alabama" +} +``` + +JSON request body can be [templatized with variables]: + +```hurl +# Create a new catty thing with JSON body: +POST https://example.org/api/cats +{ + "id": 42, + "lives": {{ lives_count }}, + "name": "{{ name }}" +} +``` + +When using JSON request body, the content type `application/json` is automatically set. + +JSON request body can be seen as syntactic sugar of [multiline string body] with `json` identifier: + +````hurl +# Create a new doggy thing with JSON body: +POST https://example.org/api/dogs +```json +{ + "id": 0, + "name": "Frieda", + "picture": "images/scottish-terrier.jpeg", + "age": 3, + "breed": "Scottish Terrier", + "location": "Lisco, Alabama" +} +``` +```` + +##### XML body + +XML request body is used to set a literal XML as the request body. + +```hurl +# Create a new soapy thing XML body: +POST https://example.org/InStock +Content-Type: application/soap+xml; charset=utf-8 +Content-Length: 299 +SOAPAction: "http://www.w3.org/2003/05/soap-envelope" + + + + + + GOOG + + + +``` + +XML request body can be seen as syntactic sugar of [multiline string body] with `xml` identifier: + +````hurl +# Create a new soapy thing XML body: +POST https://example.org/InStock +Content-Type: application/soap+xml; charset=utf-8 +Content-Length: 299 +SOAPAction: "http://www.w3.org/2003/05/soap-envelope" +```xml + + + + + + GOOG + + + +``` +```` + +> Contrary to JSON body, the succinct syntax of XML body can not use variables. If you need to use variables in your +> XML body, use a simple [multiline string body] with variables. + +##### GraphQL query + +GraphQL query uses [multiline string body] with `graphql` identifier: + +````hurl +POST https://example.org/starwars/graphql +```graphql +{ + human(id: "1000") { + name + height(unit: FOOT) + } +} +``` +```` + +GraphQL query body can use [GraphQL variables]: + +````hurl +POST https://example.org/starwars/graphql +```graphql +query Hero($episode: Episode, $withFriends: Boolean!) { + hero(episode: $episode) { + name + friends @include(if: $withFriends) { + name + } + } +} + +variables { + "episode": "JEDI", + "withFriends": false +} +``` +```` + +GraphQL query, as every multiline string body, can use Hurl variables. + +````hurl +POST https://example.org/starwars/graphql +```graphql +{ + human(id: "{{human_id}}") { + name + height(unit: FOOT) + } +} +``` +```` + +> Hurl variables and GraphQL variables can be mixed in the same body. + +##### Multiline string body + +For text based body that are neither JSON nor XML, one can use multiline string, started and ending with +```. + +````hurl +POST https://example.org/models +``` +Year,Make,Model,Description,Price +1997,Ford,E350,"ac, abs, moon",3000.00 +1999,Chevy,"Venture ""Extended Edition""","",4900.00 +1999,Chevy,"Venture ""Extended Edition, Very Large""",,5000.00 +1996,Jeep,Grand Cherokee,"MUST SELL! air, moon roof, loaded",4799.00 +``` +```` + +The standard usage of a multiline string is: + +```` +``` +line1 +line2 +line3 +``` +```` + +is evaluated as "line1\nline2\nline3\n". + +Multiline string body can use language identifier, like `json`, `xml` or `graphql`. Depending on the language identifier, +an additional 'Content-Type' request header is sent, and the real body (bytes sent over the wire) can be different from the +raw multiline text. + +````hurl +POST https://example.org/api/dogs +```json +{ + "id": 0, + "name": "Frieda", +} +``` +```` + +##### Oneline string body + +For text based body that do not contain newlines, one can use oneline string, started and ending with `. + +```hurl +POST https://example.org/helloworld +`Hello world!` +``` + +##### Base64 body + +Base64 body is used to set binary data as the request body. + +Base64 body starts with `base64,` and end with `;`. MIME's Base64 encoding is supported (newlines and white spaces may be +present anywhere but are to be ignored on decoding), and `=` padding characters might be added. + +```hurl +POST https://example.org +# Some random comments before body +base64,TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIG +FkaXBpc2NpbmcgZWxpdC4gSW4gbWFsZXN1YWRhLCBuaXNsIHZlbCBkaWN0dW0g +aGVuZHJlcml0LCBlc3QganVzdG8gYmliZW5kdW0gbWV0dXMsIG5lYyBydXRydW +0gdG9ydG9yIG1hc3NhIGlkIG1ldHVzLiA=; +``` + +##### Hex body + +Hex body is used to set binary data as the request body. + +Hex body starts with `hex,` and end with `;`. + +```hurl +PUT https://example.org +# Send a café, encoded in UTF-8 +hex,636166c3a90a; +``` + +##### File body + +To use the binary content of a local file as the body request, file body can be used. File body starts with +`file,` and ends with `;`` + +```hurl +POST https://example.org +# Some random comments before body +file,data.bin; +``` + +File are relative to the input Hurl file, and cannot contain implicit parent directory (`..`). You can use +[`--file-root` option] to specify the root directory of all file nodes. + +[method]: #method +[URL]: #url +[headers]: #headers +[Headers]: #headers +[query parameters]: #query-parameters +[form parameters]: #form-parameters +[multipart form data]: #multipart-form-data +[cookies]: #cookies +[basic authentication]: #basic-authentication +[body]: #body +[query parameters section]: #query-parameters +[HTML form]: https://developer.mozilla.org/en-US/docs/Learn/Forms +[multiline string body]: #multiline-string-body +[oneline string body]: #oneline-string-body +[body section]: #body +[multipart/form-data on MDN]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST +[`--file-root` option]: /docs/manual.md#file-root +[JSON]: https://www.json.org +[XML]: https://en.wikipedia.org/wiki/XML +[Base64]: https://en.wikipedia.org/wiki/Base64 +[hexadecimal string]: #hex-body +[included file]: #file-body +[`--file-root` option]: /docs/manual.md#file-root +[`-u/--user` option]: /docs/manual.md#user +[Hurl unicode literals \u{20}]: /docs/hurl-file.md#special-characters-in-strings +[Authorization]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization +[`--location`]: /docs/manual.md#location +[`--verbose`]: /docs/manual.md#verbose +[`--insecure`]: /docs/manual.md#insecure +[templatized with variables]: /docs/templates.md#templating-body +[GraphQL queries]: #graphql-query +[GraphQL variables]: https://graphql.org/learn/queries/#variables +[options]: #options + +## WWW + +[https://hurl.dev](https://hurl.dev)