Welcome!
" +``` + +The encoding used to decode the response body bytes to a string is based on the `charset` value in the `Content-Type` +header response. + +```hurl +# Our HTML response is encoded with GB 2312 (see https://en.wikipedia.org/wiki/GB_2312) +GET https://example.org/cn +HTTP 200 +[Asserts] +header "Content-Type" == "text/html; charset=gb2312" +# bytes of the response, without any text decoding: +bytes contains hex,c4e3bac3cac0bde7; # 你好世界 encoded in GB 2312 +# text of the response, decoded with GB 2312: +body contains "你好世界" +``` + +If the `Content-Type` response header doesn't include any encoding hint, a [`decode` filter](#file-format-filters-decode) can be used to explicitly +decode the response body bytes. + +```hurl +# Our HTML response is encoded using GB 2312. +# But, the 'Content-Type' HTTP response header doesn't precise any charset, +# so we decode explicitly the bytes. +GET https://example.org/cn +HTTP 200 +[Asserts] +header "Content-Type" == "text/html" +bytes contains hex,c4e3bac3cac0bde7; # 你好世界 encoded in GB2312 +bytes decode "gb2312" contains "你好世界" +``` + +Body asserts are automatically decompressed based on the value of `Content-Encoding` response header. So, +whatever is the response compression (`gzip`, `brotli`) etc... asserts values don't depend on the content encoding. + +```hurl +# Request a gzipped reponse, the `body` asserts works with ungzipped response +GET https://example.org +Accept-Encoding: gzip +HTTP 200 +[Asserts] +header "Content-Encoding" == "gzip" +body contains "Welcome!
" + +# Without content encoding, asserts remains identical +GET https://example.org +HTTP 200 +[Asserts] +header "Content-Encoding" not exists +body contains "Welcome!
" +``` + +#### Bytes assert {#file-format-asserting-response-bytes-assert} + +Check the value of the received HTTP response body as a bytestream. Body assert consists of the keyword `bytes` +followed by a predicate function and value. + +```hurl +GET https://example.org/data.bin +HTTP 200 +[Asserts] +bytes startsWith hex,efbbbf; +bytes count == 12424 +header "Content-Length" == "12424" +``` + +Like `body` assert, `bytes` assert works _after_ content encoding decompression (so the predicates values are not +affected by `Content-Encoding` response header value). + +#### XPath assert {#file-format-asserting-response-xpath-assert} + +Check the value of a [XPath](https://en.wikipedia.org/wiki/XPath) query on the received HTTP body decoded as a string (using the `charset` value in the +`Content-Type` header response). Currently, only XPath 1.0 expression can be used. Body assert consists of the +keyword `xpath` followed by a predicate function and value. Values can be string, +boolean or number depending on the XPath query. + +Let's say we want to check this HTML response: + +```plain +$ curl -v https://example.org + +< HTTP/1.1 200 OK +< Content-Type: text/html; charset=UTF-8 +... + + + +Example
+This domain is for use in illustrative examples in documents. You may use this domain in literature without prior coordination or asking for permission.
+ ++xpath "//p" count == 2 # Similar assert for
+xpath "boolean(count(//h2))" == false # Check there is no
+xpath "//h2" not exists # Similar assert for
+```
+
+XML Namespaces are also supported. Let's say you want to check this XML response:
+
+```xml
+
+
+
+ Cheaper by the Dozen
+ 1568491379
+
+```
+
+This XML response can be tested with the following Hurl file:
+
+```hurl
+GET http://localhost:8000/assert-xpath
+HTTP 200
+[Asserts]
+
+xpath "string(//bk:book/bk:title)" == "Cheaper by the Dozen"
+xpath "string(//*[name()='bk:book']/*[name()='bk:title'])" == "Cheaper by the Dozen"
+xpath "string(//*[local-name()='book']/*[local-name()='title'])" == "Cheaper by the Dozen"
+
+xpath "string(//bk:book/isbn:number)" == "1568491379"
+xpath "string(//*[name()='bk:book']/*[name()='isbn:number'])" == "1568491379"
+xpath "string(//*[local-name()='book']/*[local-name()='number'])" == "1568491379"
+```
+
+The XPath expressions `string(//bk:book/bk:title)` and `string(//bk:book/isbn:number)` are written with `bk` and `isbn`
+namespaces.
+
+> For convenience, the first default namespace can be used with `_`
+
+#### JSONPath assert {#file-format-asserting-response-jsonpath-assert}
+
+Check the value of a [JSONPath](https://goessner.net/articles/JsonPath/) query on the received HTTP body decoded as a JSON document. JSONPath assert consists
+of the keyword `jsonpath` followed by a predicate function and value.
+
+Let's say we want to check this JSON response:
+
+```plain
+curl -v http://httpbin.org/json
+
+< HTTP/1.1 200 OK
+< Content-Type: application/json
+...
+
+{
+ "slideshow": {
+ "author": "Yours Truly",
+ "date": "date of publication",
+ "slides": [
+ {
+ "title": "Wake up to WonderWidgets!",
+ "type": "all"
+ },
+ ...
+ ],
+ "title": "Sample Slide Show"
+ }
+}
+```
+
+With Hurl, we can write multiple JSONPath asserts describing the DOM content:
+
+```hurl
+GET http://httpbin.org/json
+HTTP 200
+[Asserts]
+jsonpath "$.slideshow.author" == "Yours Truly"
+jsonpath "$.slideshow.slides[0].title" contains "Wonder"
+jsonpath "$.slideshow.slides" count == 2
+jsonpath "$.slideshow.date" != null
+jsonpath "$.slideshow.slides[*].title" contains "Mind Blowing!"
+```
+
+> Explain that the value selected by the JSONPath is coerced to a string when only
+> one node is selected.
+
+In `matches` predicates, metacharacters beginning with a backslash (like `\d`, `\s`) must be escaped. Alternatively,
+`matches` predicate support [JavaScript-like Regular expression syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions) to enhance the readability:
+
+```hurl
+GET https://example.org/hello
+HTTP 200
+[Asserts]
+
+# Predicate value with matches predicate:
+jsonpath "$.date" matches "^\\d{4}-\\d{2}-\\d{2}$"
+jsonpath "$.name" matches "Hello [a-zA-Z]+!"
+
+# Equivalent syntax:
+jsonpath "$.date" matches /^\d{4}-\d{2}-\d{2}$/
+jsonpath "$.name" matches /Hello [a-zA-Z]+!/
+```
+
+#### Regex assert {#file-format-asserting-response-regex-assert}
+
+Check that the HTTP received body, decoded as text, matches a regex pattern.
+
+```hurl
+GET https://example.org/hello
+HTTP 200
+[Asserts]
+regex "^(\\d{4}-\\d{2}-\\d{2})$" == "2018-12-31"
+# Same assert as previous using regex literals
+regex /^(\d{4}-\d{2}-\d{2})$/ == "2018-12-31"
+```
+
+The regex pattern must have at least one capture group, otherwise the assert will fail. The assertion is done on the
+captured group value. When the regex pattern is a double-quoted string, metacharacters beginning with a backslash in the
+pattern (like `\d`, `\s`) must be escaped; literal pattern enclosed by `/` can also be used to avoid metacharacters
+escaping.
+
+The regex syntax is documented at . For instance, once can use [flags](https://docs.rs/regex/latest/regex/#grouping-and-flags)
+to enable case-insensitive match:
+
+```hurl
+GET https://example.org/hello
+HTTP 200
+[Asserts]
+regex /(?i)hello (\w+)!/ == "World"
+```
+
+#### SHA-256 assert {#file-format-asserting-response-sha-256-assert}
+
+Check response body [SHA-256](https://en.wikipedia.org/wiki/SHA-2) hash.
+
+```hurl
+GET https://example.org/data.tar.gz
+HTTP 200
+[Asserts]
+sha256 == hex,039058c6f2c0cb492c533b0a4d14ef77cc0f78abccced5287d84a1a2011cfb81;
+```
+
+Like `body` assert, `sha256` assert works _after_ content encoding decompression (so the predicates values are not
+affected by `Content-Encoding` response header). For instance, if we have a resource `a.txt` on a server with a
+given hash `abcdef`, `sha256` value is not affected by `Content-Encoding`:
+
+```hurl
+# Without content encoding compression:
+GET https://example.org/a.txt
+HTTP 200
+[Asserts]
+sha256 == hex,abcdef;
+
+# With content encoding compression:
+GET https://example.org/a.txt
+Accept-Encoding: brotli
+HTTP 200
+[Asserts]
+header "Content-Encoding" == "brotli"
+sha256 == hex,abcdef;
+```
+
+#### MD5 assert {#file-format-asserting-response-md5-assert}
+
+Check response body [MD5](https://en.wikipedia.org/wiki/MD5) hash.
+
+```hurl
+GET https://example.org/data.tar.gz
+HTTP 200
+[Asserts]
+md5 == hex,ed076287532e86365e841e92bfc50d8c;
+```
+
+Like `sha256` asserts, `md5` assert works _after_ content encoding decompression (so the predicates values are not
+affected by `Content-Encoding` response header)
+
+#### URL assert {#file-format-asserting-response-url-assert}
+
+Check the last fetched URL. This is most meaningful if you have told Hurl to follow redirection (see [`[Options]`section][options](#file-format-request-options) or
+[`--location` option](#getting-started-manual-location)). URL assert consists of the keyword `url` followed by a predicate function and value.
+
+```hurl
+GET https://example.org/redirecting
+[Options]
+location: true
+HTTP 200
+[Asserts]
+url == "https://example.org/redirected"
+```
+
+#### Redirects assert {#file-format-asserting-response-redirects-assert}
+
+Check each step of redirection. This is most meaningful if you have told Hurl to follow redirection (see [`[Options]`section][options](#file-format-request-options) or
+[`--location` option](#getting-started-manual-location)). Redirects assert consists of the keyword `redirects` followed by a predicate function and value. The `redirects`
+query returns a collection of redirections that can be tested with a [`location` filter](#file-format-filters-location):
+
+```hurl
+GET https://example.org/redirecting/1
+[Options]
+location: true
+HTTP 200
+[Asserts]
+redirects count == 3
+redirects nth 0 location == "https://example.org/redirecting/2"
+redirects nth 1 location == "https://example.org/redirecting/3"
+redirects nth 2 location == "https://example.org/redirected"
+```
+
+#### IP address assert {#file-format-asserting-response-ip-address-assert}
+
+Check the IP address of the last connection. The value of the `ip` query is a string.
+
+> Predicates `isIpv4` and `isIpv6` are available to check if a particular string matches an IPv4 or IPv6 address and
+> can use with `ip` queries.
+
+```hurl
+GET https://example.org/hello
+HTTP 200
+[Asserts]
+ip isIpv4
+ip not isIpv6
+ip == "172.16.45.87"
+```
+
+#### Variable assert {#file-format-asserting-response-variable-assert}
+
+```hurl
+# Test that the XML endpoint return 200 pets
+GET https://example.org/api/pets
+HTTP 200
+[Captures]
+pets: xpath "//pets"
+[Asserts]
+variable "pets" count == 200
+```
+
+#### Duration assert {#file-format-asserting-response-duration-assert}
+
+Check the total duration (sending plus receiving time) of the HTTP transaction.
+
+```hurl
+GET https://example.org/helloworld
+HTTP 200
+[Asserts]
+duration < 1000 # Check that response time is less than one second
+```
+
+#### SSL certificate assert {#file-format-asserting-response-ssl-certificate-assert}
+
+Check the SSL certificate properties. Certificate assert consists of the keyword `certificate`, followed by the
+certificate attribute value.
+
+The following attributes are supported: `Subject`, `Issuer`, `Start-Date`, `Expire-Date` and `Serial-Number`.
+
+```hurl
+GET https://example.org
+HTTP 200
+[Asserts]
+certificate "Subject" == "CN=example.org"
+certificate "Issuer" == "C=US, O=Let's Encrypt, CN=R3"
+certificate "Expire-Date" daysAfterNow > 15
+certificate "Serial-Number" matches "[0-9af]+"
+```
+
+
+
+
+
+## Filters {#file-format-filters-filters}
+
+### Definition {#file-format-filters-definition}
+
+[Captures](#file-format-capturing-response) and [asserts](#file-format-asserting-response) share a common structure: query. A query is used to extract data from an HTTP response; this data
+can come from the HTTP response body, the HTTP response headers or from the HTTP meta-information (like `duration` for instance)...
+
+In this example, the query __`jsonpath "$.books[0].name"`__ is used in a capture to save data and in an assert to test
+the HTTP response body.
+
+__Capture__:
+
+
+
+ namevariable
+ :
+ jsonpath "$.books[0].name"query
+
+
+
+__Assert__:
+
+
+
+ jsonpath "$.books[0].name"query
+ == "Dune"predicate
+
+
+
+In both case, the query is exactly the same: queries are the core structure of asserts and captures. Sometimes, you want
+to process data extracted by queries: that's the purpose of __filters__.
+
+Filters are used to transform value extracted by a query and can be used in asserts and captures to refine data. Filters
+__can be chained__, allowing for fine-grained data extraction.
+
+
+
+
+ jsonpath "$.name"query
+ split "," nth 02 filters
+ == "Herbert"predicate
+
+
+
+
+### Example {#file-format-filters-example}
+
+```hurl
+GET https://example.org/api
+HTTP 200
+[Captures]
+name: jsonpath "$.user.id" replaceRegex /\d/ "x"
+[Asserts]
+header "x-servers" split "," count == 2
+header "x-servers" split "," nth 0 == "rec1"
+header "x-servers" split "," nth 1 == "rec3"
+jsonpath "$.books" count == 12
+```
+
+### Description {#file-format-filters-description}
+
+| Filter | Description | Input | Output |
+|-----------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------|--------------------|----------|
+| [base64Decode](#file-format-filters-base64decode) | Decodes a [Base64 encoded string] into bytes. | string | bytes |
+| [base64Encode](#file-format-filters-base64encode) | Encodes bytes into [Base64 encoded string]. | bytes | string |
+| [base64UrlSafeDecode](#file-format-filters-base64urlsafedecode) | Decodes a Base64 encoded string into bytes (using [Base64 URL safe encoding]). | string | bytes |
+| [base64UrlSafeEncode](#file-format-filters-base64urlsafeencode) | Encodes bytes into Base64 encoded string (using [Base64 URL safe encoding]). | bytes | string |
+| [count](#file-format-filters-count) | Counts the number of items in a collection. | collection | number |
+| [daysAfterNow](#file-format-filters-daysafternow) | Returns the number of days between now and a date in the future. | date | number |
+| [daysBeforeNow](#file-format-filters-daysbeforenow) | Returns the number of days between now and a date in the past. | date | number |
+| [decode](#file-format-filters-decode) | Decodes bytes to string using encoding. | bytes | string |
+| [first](#file-format-filters-first) | Returns the first element from a collection. | collection | any |
+| [format](#file-format-filters-format) | Formats a date to a string given [a specification format]. | date | string |
+| [htmlEscape](#file-format-filters-htmlescape) | Converts the characters `&`, `<` and `>` to HTML-safe sequence. | string | string |
+| [htmlUnescape](#file-format-filters-htmlunescape) | Converts all named and numeric character references (e.g. `>`, `>`, `>`) to the corresponding Unicode characters. | string | string |
+| [jsonpath](#file-format-filters-jsonpath) | Evaluates a [JSONPath] expression. | string | any |
+| [last](#file-format-filters-last) | Returns the last element from a collection. | collection | any |
+| [location](#file-format-filters-location) | Returns the target location URL of a redirection. | response | string |
+| [nth](#file-format-filters-nth) | Returns the element from a collection at a zero-based index, accepts negative indices for indexing from the end of the collection. | collection | any |
+| [regex](#file-format-filters-regex) | Extracts regex capture group. Pattern must have at least one capture group. | string | string |
+| [replace](#file-format-filters-replace) | Replaces all occurrences of old string with new string. | string | string |
+| [replaceRegex](#file-format-filters-replaceregex) | Replaces all occurrences of a pattern with new string. | string | string |
+| [split](#file-format-filters-split) | Splits to a list of strings around occurrences of the specified delimiter. | string | string |
+| [toDate](#file-format-filters-toDate) | Converts a string to a date given [a specification format]. | string | date |
+| [toFloat](#file-format-filters-tofloat) | Converts value to float number. | string \ | number |
+| [toHex](#file-format-filters-tohex) | Converts bytes to hexadecimal string. | bytes | string |
+| [toInt](#file-format-filters-toint) | Converts value to integer number. | string \ | number |
+| [toString](#file-format-filters-tostring) | Converts value to string. | any | string |
+| [urlDecode](#file-format-filters-urldecode) | Replaces %xx escapes with their single-character equivalent. | string | string |
+| [urlEncode](#file-format-filters-urlencode) | Percent-encodes all the characters which are not included in unreserved chars (see [RFC3986]) with the exception of forward slash (/). | string | string |
+| [urlQueryParam](#file-format-filters-urlqueryparam) | Returns the value of a query parameter in a URL. | string | string |
+| [xpath](#file-format-filters-xpath) | Evaluates a [XPath] expression. | string | string |
+
+#### base64Decode {#file-format-filters-base64decode}
+
+Decodes a [Base64 encoded string](https://datatracker.ietf.org/doc/html/rfc4648#section-4) into bytes.
+
+```hurl
+GET https://example.org/api
+HTTP 200
+[Asserts]
+jsonpath "$.token" base64Decode == hex,3c3c3f3f3f3e3e;
+```
+
+#### base64Encode {#file-format-filters-base64encode}
+
+Encodes bytes into [Base64 encoded string](https://datatracker.ietf.org/doc/html/rfc4648#section-4).
+
+```hurl
+GET https://example.org/api
+HTTP 200
+[Asserts]
+bytes base64Encode == "PDw/Pz8+Pg=="
+```
+
+#### base64UrlSafeDecode {#file-format-filters-base64urlsafedecode}
+
+Decodes a Base64 encoded string into bytes (using [Base64 URL safe encoding](https://datatracker.ietf.org/doc/html/rfc4648#section-5)).
+
+```hurl
+GET https://example.org/api
+HTTP 200
+[Asserts]
+jsonpath "$.token" base64UrlSafeDecode == hex,3c3c3f3f3f3e3e;
+```
+
+#### base64UrlSafeEncode {#file-format-filters-base64urlsafeencode}
+
+Encodes bytes into Base64 encoded string (using [Base64 URL safe encoding](https://datatracker.ietf.org/doc/html/rfc4648#section-5)).
+
+```hurl
+GET https://example.org/api
+HTTP 200
+[Asserts]
+bytes base64UrlSafeEncode == "PDw_Pz8-Pg"
+```
+
+#### count {#file-format-filters-count}
+
+Counts the number of items in a collection.
+
+```hurl
+GET https://example.org/api
+HTTP 200
+[Asserts]
+jsonpath "$.books" count == 12
+```
+
+#### daysAfterNow {#file-format-filters-daysafternow}
+
+Returns the number of days between now and a date in the future.
+
+```hurl
+GET https://example.org
+HTTP 200
+[Asserts]
+certificate "Expire-Date" daysAfterNow > 15
+```
+
+#### daysBeforeNow {#file-format-filters-daysbeforenow}
+
+Returns the number of days between now and a date in the past.
+
+```hurl
+GET https://example.org
+HTTP 200
+[Asserts]
+certificate "Start-Date" daysBeforeNow < 100
+```
+
+#### decode {#file-format-filters-decode}
+
+Decodes bytes to string using encoding.
+
+```hurl
+# The 'Content-Type' HTTP response header does not precise the charset 'gb2312'
+# so body must be decoded explicitly by Hurl before processing any text based assert
+GET https://example.org/hello_china
+HTTP 200
+[Asserts]
+header "Content-Type" == "text/html"
+# Content-Type has no encoding clue, we must decode ourselves the body response.
+bytes decode "gb2312" xpath "string(//body)" == "你好世界"
+```
+
+#### first {#file-format-filters-first}
+
+Returns the first element from a collection.
+
+```hurl
+GET https://example.org
+HTTP 200
+[Asserts]
+jsonpath "$.books" first == "Dune"
+```
+
+#### format {#file-format-filters-format}
+
+Formats a date to a string given [a specification format](https://docs.rs/chrono/latest/chrono/format/strftime/index.html).
+
+```hurl
+GET https://example.org
+HTTP 200
+[Asserts]
+cookie "LSID[Expires]" format "%a, %d %b %Y %H:%M:%S" == "Wed, 13 Jan 2021 22:23:01"
+```
+
+#### htmlEscape {#file-format-filters-htmlescape}
+
+Converts the characters `&`, `<` and `>` to HTML-safe sequence.
+
+```hurl
+GET https://example.org/api
+HTTP 200
+[Asserts]
+jsonpath "$.text" htmlEscape == "a > b"
+```
+
+#### htmlUnescape {#file-format-filters-htmlunescape}
+
+Converts all named and numeric character references (e.g. `>`, `>`, `>`) to the corresponding Unicode characters.
+
+```hurl
+GET https://example.org/api
+HTTP 200
+[Asserts]
+jsonpath "$.escaped_html[1]" htmlUnescape == "Foo © bar 𝌆"
+```
+
+#### jsonpath {#file-format-filters-jsonpath}
+
+Evaluates a [JSONPath](https://goessner.net/articles/JsonPath/) expression.
+
+```hurl
+GET https://example.org/api
+HTTP 200
+[Captures]
+books: xpath "string(//body/@data-books)"
+[Asserts]
+variable "books" jsonpath "$[0].name" == "Dune"
+variable "books" jsonpath "$[0].author" == "Franck Herbert"
+```
+
+#### last {#file-format-filters-last}
+
+Returns the last element from a collection.
+
+```hurl
+GET https://example.org
+HTTP 200
+[Asserts]
+jsonpath "$.books" last == "Les Misérables"
+```
+
+#### location {#file-format-filters-location}
+
+Returns the target URL location of a redirection; the returned URL is always absolute, contrary to the `Location` header from
+which it's originated that can be absolute or relative.
+
+```hurl
+GET https://example.org/step1
+[Options]
+location: true
+HTTP 200
+[Asserts]
+redirects count == 2
+redirects nth 0 location == "https://example.org/step2"
+redirects nth 1 location == "https://example.org/step3"
+```
+
+#### nth {#file-format-filters-nth}
+
+Returns the element from a collection at a zero-based index, accepts negative indices for indexing from the end of the collection.
+
+```hurl
+GET https://example.org/api
+HTTP 200
+[Asserts]
+jsonpath "$.books" nth 2 == "Children of Dune"
+```
+
+#### regex {#file-format-filters-regex}
+
+Extracts regex capture group. Pattern must have at least one capture group.
+
+```hurl
+GET https://example.org/foo
+HTTP 200
+[Captures]
+param1: header "header1"
+param2: header "header2" regex "Hello (.*)!"
+param3: header "header2" regex /Hello (.*)!/
+param3: header "header2" regex /(?i)Hello (.*)!/
+```
+
+The regex syntax is documented at .
+
+#### replace {#file-format-filters-replace}
+
+Replaces all occurrences of old string with new string.
+
+```hurl
+GET https://example.org/foo
+HTTP 200
+[Captures]
+url: jsonpath "$.url" replace "http://" "https://"
+[Asserts]
+jsonpath "$.ips" replace ", " "|" == "192.168.2.1|10.0.0.20|10.0.0.10"
+```
+
+#### replaceRegex {#file-format-filters-replaceregex}
+
+Replaces all occurrences of a pattern with new string.
+
+```hurl
+GET https://example.org/foo
+HTTP 200
+[Captures]
+url: jsonpath "$.id" replaceRegex /\d/ "x"
+[Asserts]
+jsonpath "$.message" replaceRegex "B[aoi]b" "Dude" == "Welcome Dude!"
+```
+
+#### split {#file-format-filters-split}
+
+Splits to a list of strings around occurrences of the specified delimiter.
+
+```hurl
+GET https://example.org/foo
+HTTP 200
+[Asserts]
+jsonpath "$.ips" split ", " count == 3
+```
+
+#### toDate {#file-format-filters-todate}
+
+Converts a string to a date given [a specification format](https://docs.rs/chrono/latest/chrono/format/strftime/index.html).
+
+```hurl
+GET https:///example.org
+HTTP 200
+[Asserts]
+header "Expires" toDate "%a, %d %b %Y %H:%M:%S GMT" daysBeforeNow > 1000
+```
+
+ISO 8601 / RFC 3339 date and time format have shorthand format `%+`:
+
+```hurl
+GET https://example.org/api/books
+HTTP 200
+[Asserts]
+jsonpath "$.published" == "2023-01-23T18:25:43.511Z"
+jsonpath "$.published" toDate "%Y-%m-%dT%H:%M:%S%.fZ" format "%A" == "Monday"
+jsonpath "$.published" toDate "%+" format "%A" == "Monday" # %+ can be used to parse ISO 8601 / RFC 3339
+```
+
+#### toFloat {#file-format-filters-tofloat}
+
+Converts value to float number.
+
+```hurl
+GET https://example.org/foo
+HTTP 200
+[Asserts]
+jsonpath "$.pi" toFloat == 3.14
+```
+
+#### toHex {#file-format-filters-tohex}
+
+Converts bytes to hexadecimal string.
+
+```hurl
+GET https://example.org/foo
+HTTP 200
+[Asserts]
+bytes toHex == "d188d0b5d0bbd0bbd18b"
+```
+
+#### toInt {#file-format-filters-toint}
+
+Converts value to integer number.
+
+```hurl
+GET https://example.org/foo
+HTTP 200
+[Asserts]
+jsonpath "$.id" toInt == 123
+```
+
+#### toString {#file-format-filters-tostring}
+
+Converts value to string.
+
+```hurl
+GET https://example.org/foo
+HTTP 200
+[Asserts]
+jsonpath "$.count" toString == "42"
+```
+
+#### urlDecode {#file-format-filters-urldecode}
+
+Replaces %xx escapes with their single-character equivalent.
+
+```hurl
+GET https://example.org/foo
+HTTP 200
+[Asserts]
+jsonpath "$.encoded_url" urlDecode == "https://mozilla.org/?x=шеллы"
+```
+
+#### urlEncode {#file-format-filters-urlencode}
+
+Percent-encodes all the characters which are not included in unreserved chars (see [RFC3986](https://www.rfc-editor.org/rfc/rfc3986)) with the exception of forward slash (/).
+
+```hurl
+GET https://example.org/foo
+HTTP 200
+[Asserts]
+jsonpath "$.url" urlEncode == "https%3A//mozilla.org/%3Fx%3D%D1%88%D0%B5%D0%BB%D0%BB%D1%8B"
+```
+
+#### urlQueryParam {#file-format-filters-urlqueryparam}
+
+Returns the value of a query parameter in a URL.
+
+```hurl
+GET https://example.org/foo
+HTTP 200
+[Asserts]
+jsonpath "$.url" urlQueryParam "x" == "шеллы"
+```
+
+#### xpath {#file-format-filters-xpath}
+
+Evaluates a [XPath](https://en.wikipedia.org/wiki/XPath) expression.
+
+```hurl
+GET https://example.org/hello_gb2312
+HTTP 200
+[Asserts]
+bytes decode "gb2312" xpath "string(//body)" == "你好世界"
+```
+
+
+
+
+
+
+## Templates {#file-format-templates-templates}
+
+### Variables {#file-format-templates-variables}
+
+In Hurl file, you can generate value using two curly braces, i.e `{{my_variable}}`. For instance, if you want to reuse a
+value from an HTTP response in the next entries, you can capture this value in a variable and reuse it in a placeholder.
+
+In this example, we capture the value of a [CSRF token](https://en.wikipedia.org/wiki/Cross-site_request_forgery) from the body of the first response, and inject it
+as a header in the next POST request:
+
+```hurl
+GET https://example.org
+HTTP 200
+[Captures]
+csrf_token: xpath "string(//meta[@name='_csrf_token']/@content)"
+
+# Do the login !
+POST https://acmecorp.net/login?user=toto&password=1234
+X-CSRF-TOKEN: {{csrf_token}}
+HTTP 302
+```
+
+In this second example, we capture the body in a variable `index`, and reuse this value in the query
+`jsonpath "$.errors[{{index}}].id"`:
+
+
+```hurl
+GET https://example.org/api/index
+HTTP 200
+[Captures]
+index: body
+
+GET https://example.org/api/status
+HTTP 200
+[Asserts]
+jsonpath "$.errors[{{index}}].id" == "error"
+```
+
+
+### Functions {#file-format-templates-functions}
+
+Besides variables, functions can be used to generate dynamic values. Current functions are:
+
+| Function | Description |
+|-------------|----------------------------------------------------------------|
+| `newUuid` | Generates an [UUID v4 random string](https://en.wikipedia.org/wiki/Universally_unique_identifier) |
+| `newDate` | Generates an [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339) UTC date string, at the current time |
+
+In the following example, we use `newDate` to generate a dynamic query parameter:
+
+```hurl
+GET https://example.org/api/foo
+[Query]
+date: {{newDate}}
+HTTP 200
+```
+
+We run a `GET` request to `https://example.org/api/foo?date=2024%2D12%2D02T10%3A35%3A44%2E461731Z` where the `date`
+query parameter value is `2024-12-02T10:35:44.461731Z` URL encoded.
+
+In this second example, we use `newUuid` function to generate an email dynamically:
+
+```hurl
+POST https://example.org/api/foo
+{
+ "name": "foo",
+ "email": "{{newUuid}}@test.com"
+}
+```
+
+When run, the request body will be:
+
+```
+{
+ "name": "foo",
+ "email": "0531f78f-7f87-44be-a7f2-969a1c4e6d97@test.com"
+}
+```
+
+
+### Types {#file-format-templates-types}
+
+Values generated from function and variables are typed, and can be either string, bool, number, `null` or collections. Depending on the value type,
+templates can be rendered differently. Let's say we have captured an integer value into a variable named
+`count`:
+
+```hurl
+GET https://sample/counter
+
+HTTP 200
+[Captures]
+count: jsonpath "$.results[0]"
+```
+
+The following entry:
+
+```hurl
+GET https://sample/counter/{{count}}
+
+HTTP 200
+[Asserts]
+jsonpath "$.id" == "{{count}}"
+```
+
+will be rendered at runtime to:
+
+```hurl
+GET https://sample/counter/458
+
+HTTP 200
+[Asserts]
+jsonpath "$.id" == "458"
+```
+
+resulting in a comparison between the [JSONPath](#file-format-asserting-response-jsonpath-assert) expression and a string value.
+
+On the other hand, the following assert:
+
+```hurl
+GET https://sample/counter/{{count}}
+
+HTTP 200
+[Asserts]
+jsonpath "$.index" == {{count}}
+```
+
+will be rendered at runtime to:
+
+```hurl
+GET https://sample/counter/458
+
+HTTP 200
+[Asserts]
+jsonpath "$.index" == 458
+```
+
+resulting in a comparison between the [JSONPath](#file-format-asserting-response-jsonpath-assert) expression and an integer value.
+
+So if you want to use typed values (in asserts for instances), you can use `{{my_var}}`.
+If you're interested in the string representation of a variable, you can surround the variable with double quotes
+, as in `"{{my_var}}"`.
+
+> When there is no possible ambiguities, like using a variable in an URL, or
+> in a header, you can omit the double quotes. The value will always be rendered
+> as a string.
+
+### Injecting Variables {#file-format-templates-injecting-variables}
+
+Variables can be injected in a Hurl file:
+
+- by using [`--variable` option](#getting-started-manual-variable)
+- by using [`--variables-file` option](#getting-started-manual-variables-file)
+- by defining environment variables, for instance `HURL_foo=bar`
+- by defining variables in an [`[Options]` section][options](#file-format-request-options)
+
+Lets' see how to inject variables, given this `test.hurl`:
+
+```hurl
+GET https://{{host}}/{{id}}/status
+HTTP 304
+
+GET https://{{host}}/health
+HTTP 200
+```
+
+#### `variable` option {#file-format-templates-variable-option}
+
+Variable can be defined with command line option:
+
+```shell
+$ hurl --variable host=example.net --variable id=1234 test.hurl
+```
+
+
+#### `variables-file` option {#file-format-templates-variables-file-option}
+
+We can also define all injected variables in a file:
+
+```shell
+$ hurl --variables-file vars.env test.hurl
+```
+
+where `vars.env` is
+
+```
+host=example.net
+id=1234
+```
+
+#### Environment variable {#file-format-templates-environment-variable}
+
+We can use environment variables in the form of `HURL_name=value`:
+
+```shell
+$ export HURL_host=example.net
+$ export HURL_id=1234
+$ hurl test.hurl
+```
+
+#### Options sections {#file-format-templates-options-sections}
+
+We can define variables in `[Options]` section. Variables defined in a section are available for the next requests.
+
+```hurl
+GET https://{{host}}/{{id}}/status
+[Options]
+variable: host=example.net
+variable: id=1234
+HTTP 304
+
+GET https://{{host}}/health
+HTTP 200
+```
+
+#### Secrets {#file-format-templates-secrets}
+
+Secrets are variables which value is redacted from standard error logs (for instance using [`--very-verbose`](#getting-started-manual-very-verbose)) and [reports](#getting-started-running-tests-generating-report).
+Secrets are injected through command-line with [`--secret` option](#getting-started-manual-secret):
+
+```shell
+$ hurl --secret token=FooBar test.hurl
+```
+
+Values are redacted by _exact matching_: if a secret value is transformed, and you want to redact also the transformed value,
+you can add as many secrets as there are transformed values. Even if a secret is not used as a variable, all secrets values
+will be redacted from messages and logs.
+
+```shell
+$ hurl --secret token=FooBar \
+ --secret token_alt_0=FOOBAR \
+ --secret token_alt_1=foobar \
+ test.hurl
+```
+
+> Secrets __are not redacted__ from HTTP responses outputted on standard output as Hurl considers the standard output as
+> the correct unaltered output of a run. With this call `$ hurl --secret token=FooBar test.hurl`,
+> the HTTP response is outputted unaltered and `FooBar` can appear in the HTTP response. Options that transforms Hurl
+> output on standard output, like [`--include`](#getting-started-manual-include) or [`--json`](#getting-started-manual-json) works the same. [JSON report](#getting-started-running-tests-json-report) also saves each unaltered HTTP
+> response on disk so extra care must be taken when secrets are in the HTTP response body.
+
+
+### Templating Body {#file-format-templates-templating-body}
+
+Variables and functions can be used in [JSON body](#file-format-request-json-body):
+
+~~~hurl
+PUT https://example.org/api/hits
+{
+ "key0": "{{a_string}}",
+ "key1": {{a_bool}},
+ "key2": {{a_null}},
+ "key3": {{a_number}},
+ "key4": "{{newDate}}"
+}
+~~~
+
+Note that we're writing a kind of JSON body directly without any delimitation marker. For the moment, [XML body](#file-format-request-xml-body) can't
+use variables directly. In order to templatize a XML body, you can use [multiline string body](#file-format-request-multiline-string-body) with variables and
+functions. The multiline string body allows to templatize any text based body (JSON, XML, CSV etc...):
+
+Multiline string body delimited by `` ``` ``:
+
+~~~hurl
+PUT https://example.org/api/hits
+Content-Type: application/json
+```
+{
+ "key0": "{{a_string}}",
+ "key1": {{a_bool}},
+ "key2": {{a_null}},
+ "key3": {{a_number}},
+ "key4: "{{newDate}}"
+}
+```
+~~~
+
+Variables can be initialized via command line:
+
+```shell
+$ hurl --variable a_string=apple --variable a_bool=true --variable a_null=null --variable a_number=42 test.hurl
+```
+
+Resulting in a PUT request with the following JSON body:
+
+```
+{
+ "key0": "apple",
+ "key1": true,
+ "key2": null,
+ "key3": 42,
+ "key4": "2024-12-02T13:39:45.936643Z"
+}
+```
+
+
+
+
+
+## Grammar {#file-format-grammar-grammar}
+
+### Definitions {#file-format-grammar-definitions}
+
+Short description:
+
+- operator | denotes alternative,
+- operator * denotes iteration (zero or more),
+- operator + denotes iteration (one or more),
+
+### Syntax Grammar {#file-format-grammar-syntax-grammar}
+
+General
+
+request(used by entry)
+
+method(used by request)[A-Z]+
+version(used by response) HTTP/1.0
+|HTTP/1.1
+|HTTP/2
+|HTTP
+status(used by response)[0-9]+
+
+
+Sections
request-section(used by request)
+response-section(used by response)
+query-string-params-section(used by request-section)
+form-params-section(used by request-section)
+multipart-form-data-section(used by request-section)
+cookies-section(used by request-section)
+captures-section(used by response-section)
+asserts-section(used by response-section)
+basic-auth-section(used by request-section)
+options-section(used by request-section)
+key-value(used by header, query-string-params-section, form-params-section, cookies-section, basic-auth-section, multipart-form-data-param)
+multipart-form-data-param(used by multipart-form-data-section)
+filename-param(used by multipart-form-data-param)
+filename-value(used by filename-param)
+filename-content-type(used by filename-value)
+capture(used by captures-section)
+
+option(used by options-section)lt*
+(aws-sigv4-option|ca-certificate-option|client-certificate-option|client-key-option|compressed-option|connect-to-option|connect-timeout-option|delay-option|follow-redirect-option|follow-redirect-trusted-option|header-option|http10-option|http11-option|http2-option|http3-option|insecure-option|ipv4-option|ipv6-option|limit-rate-option|max-redirs-option|max-time-option|netrc-option|netrc-file-option|netrc-optional-option|output-option|path-as-is-option|pinned-public-key-option|proxy-option|repeat-option|resolve-option|retry-option|retry-interval-option|skip-option|unix-socket-option|user-option|variable-option|verbose-option|very-verbose-option)
+aws-sigv4-option(used by option)
+
+client-certificate-option(used by option)
+client-key-option(used by option)
+compressed-option(used by option)
+connect-to-option(used by option)
+connect-timeout-option(used by option)
+delay-option(used by option)
+follow-redirect-option(used by option)
+follow-redirect-trusted-option(used by option)
+header-option(used by option)
+http10-option(used by option)
+http11-option(used by option)
+http2-option(used by option)
+http3-option(used by option)
+insecure-option(used by option)
+ipv4-option(used by option)
+ipv6-option(used by option)
+limit-rate-option(used by option)
+max-redirs-option(used by option)
+max-time-option(used by option)
+netrc-option(used by option)
+netrc-file-option(used by option)
+netrc-optional-option(used by option)
+output-option(used by option)
+path-as-is-option(used by option)
+pinned-public-key-option(used by option)
+proxy-option(used by option)
+resolve-option(used by option)
+repeat-option(used by option)
+retry-option(used by option)
+retry-interval-option(used by option)
+skip-option(used by option)
+unix-socket-option(used by option)
+user-option(used by option)
+variable-option(used by option)
+verbose-option(used by option)
+very-verbose-option(used by option)
+variable-definition(used by variable-option)
+boolean-option(used by compressed-option, follow-redirect-option, follow-redirect-trusted-option, http10-option, http11-option, http2-option, http3-option, insecure-option, ipv4-option, ipv6-option, netrc-option, netrc-optional-option, path-as-is-option, skip-option, verbose-option, very-verbose-option)
+integer-option(used by limit-rate-option, max-redirs-option, max-time-option, repeat-option, retry-option)
+duration-option(used by connect-timeout-option, delay-option, retry-interval-option)
+duration-unit(used by duration-option)ms|s|m
+variable-value(used by variable-definition)
+Query
+status-query(used by query)status
+version-query(used by query)version
+url-query(used by query)url
+ip-query(used by query)ip
+header-query(used by query)
+certificate-query(used by query)
+cookie-query(used by query)
+body-query(used by query)body
+xpath-query(used by query)
+jsonpath-query(used by query)
+regex-query(used by query)
+variable-query(used by query)
+duration-query(used by query)duration
+sha256-query(used by query)sha256
+md5-query(used by query)md5
+bytes-query(used by query)bytes
+Predicates
predicate(used by assert)
+predicate-func(used by predicate) equal-predicate
+|not-equal-predicate
+|greater-predicate
+|greater-or-equal-predicate
+|less-predicate
+|less-or-equal-predicate
+|start-with-predicate
+|end-with-predicate
+|contain-predicate
+|match-predicate
+|exist-predicate
+|is-empty-predicate
+|include-predicate
+|integer-predicate
+|float-predicate
+|boolean-predicate
+|string-predicate
+|collection-predicate
+|date-predicate
+|iso-date-predicate
+|is-ipv4-predicate
+|is-ipv6-predicate
+|is-uuid-predicate
+equal-predicate(used by predicate-func)
+not-equal-predicate(used by predicate-func)
+greater-predicate(used by predicate-func)
+greater-or-equal-predicate(used by predicate-func)
+less-predicate(used by predicate-func)
+less-or-equal-predicate(used by predicate-func)
+start-with-predicate(used by predicate-func)
+end-with-predicate(used by predicate-func)
+contain-predicate(used by predicate-func)
+match-predicate(used by predicate-func)
+exist-predicate(used by predicate-func)exists
+is-empty-predicate(used by predicate-func)isEmpty
+include-predicate(used by predicate-func)
+integer-predicate(used by predicate-func)isInteger
+float-predicate(used by predicate-func)isFloat
+boolean-predicate(used by predicate-func)isBoolean
+string-predicate(used by predicate-func)isString
+collection-predicate(used by predicate-func)isCollection
+date-predicate(used by predicate-func)isDate
+iso-date-predicate(used by predicate-func)isIsoDate
+is-ipv4-predicate(used by predicate-func)isIpv4
+is-ipv6-predicate(used by predicate-func)isIpv6
+is-uuid-predicate(used by predicate-func)isUuid
+predicate-value(used by equal-predicate, not-equal-predicate, include-predicate) boolean
+|multiline-string
+|null
+|number
+|oneline-string
+|oneline-base64
+|oneline-file
+|oneline-hex
+|quoted-string
+|placeholder
+Bytes
bytes(used by body)
+xml(used by bytes)< To Be Defined >
+oneline-base64(used by start-with-predicate, end-with-predicate, predicate-value, bytes)base64, [A-Z0-9+-= \n]+ ;
+oneline-file(used by predicate-value, bytes)
+oneline-hex(used by start-with-predicate, end-with-predicate, predicate-value, bytes)
+Strings
quoted-string(used by variable-value, header-query, cookie-query, xpath-query, jsonpath-query, regex-query, variable-query, greater-predicate, greater-or-equal-predicate, less-predicate, less-or-equal-predicate, start-with-predicate, end-with-predicate, contain-predicate, match-predicate, predicate-value, format-filter, jsonpath-filter, regex-filter, replace-filter, replace-regex-filter, split-filter, to-date-filter, url-query-param-filter, xpath-filter)
+quoted-string-content(used by quoted-string)
+quoted-string-text(used by quoted-string-content)~["\\]+
+quoted-string-escaped-char(used by quoted-string-content)
+key-string(used by key-value, filename-param, capture, variable-value)
+key-string-content(used by key-string)
+key-string-text(used by key-string-content)
+key-string-escaped-char(used by key-string-content)
+
+value-string-content(used by value-string)
+value-string-text(used by value-string-content)~[#\n\\]+
+value-string-escaped-char(used by value-string-content)
+oneline-string(used by predicate-value, bytes)
+oneline-string-content(used by oneline-string)
+oneline-string-text(used by oneline-string-content)~[#\n\\] ~`
+oneline-string-escaped-char(used by oneline-string-content)
+multiline-string(used by predicate-value, bytes)``` multiline-string-type? (, multiline-string-attribute)* lt
+(multiline-string-content|placeholder)* lt
+```
+multiline-string-type(used by multiline-string) base64
+|hex
+|json
+|xml
+|graphql
+multiline-string-attribute(used by multiline-string) escape
+|novariable
+multiline-string-content(used by multiline-string)
+multiline-string-text(used by multiline-string-content)~[\\]+ ~```
+multiline-string-escaped-char(used by multiline-string-content)
+filename(used by filename-value, ca-certificate-option, oneline-file)
+filename-content(used by filename)
+filename-text(used by filename-content)~[#;{} \n\r\\]+
+filename-escaped-char(used by filename-content)
+filename-password(used by client-certificate-option)
+filename-password-content(used by filename-password)
+filename-password-text(used by filename-password-content)~[#;{} \n\r\\]+
+filename-password-escaped-char(used by filename-password-content)
+
+JSON
json-value(used by bytes, json-key-value, json-array)
+json-object(used by json-value)
+json-key-value(used by json-object)
+json-array(used by json-value)
+json-string(used by json-value, json-key-value)
+json-string-content(used by json-string)
+json-string-text(used by json-string-content)~["\\]
+json-string-escaped-char(used by json-string-content)
+json-number(used by json-value)
+json-integer(used by json-number)
+Expression
placeholder(used by boolean-option, integer-option, duration-option, greater-predicate, greater-or-equal-predicate, less-predicate, less-or-equal-predicate, predicate-value, quoted-string, key-string, value-string, oneline-string, multiline-string, filename, filename-password, json-value, json-string, nth-filter)
+expr(used by placeholder)
+variable-name(used by variable-definition, expr)[A-Za-z] [A-Za-z_-0-9]*
+Function
function(used by expr)
+env-function(used by function)getEnv
+now-function(used by function)newDate
+uuid-function(used by function)newUuid
+Filter
base64-decode-filter
+|base64-encode-filter
+|base64-url-safe-decode-filter
+|base64-url-safe-encode-filter
+|count-filter
+|days-after-now-filter
+|days-before-now-filter
+|decode-filter
+|first-filter
+|format-filter
+|html-escape-filter
+|html-unescape-filter
+|jsonpath-filter
+|last-filter
+|location-filter
+|nth-filter
+|regex-filter
+|replace-filter
+|replace-regex-filter
+|split-filter
+|to-date-filter
+|to-float-filter
+|to-hex-filter
+|to-int-filter
+|to-string-filter
+|url-decode-filter
+|url-encode-filter
+|url-query-param-filter
+|xpath-filter
+base64-decode-filter(used by filter)base64Decode
+base64-encode-filter(used by filter)base64Encode
+base64-url-safe-decode-filter(used by filter)base64UrlSafeDecode
+base64-url-safe-encode-filter(used by filter)base64UrlSafeEncode
+count-filter(used by filter)count
+days-after-now-filter(used by filter)daysAfterNow
+days-before-now-filter(used by filter)daysBeforeNow
+decode-filter(used by filter)decode
+first-filter(used by filter)first
+format-filter(used by filter)
+html-escape-filter(used by filter)htmlEscape
+html-unescape-filter(used by filter)htmlUnescape
+jsonpath-filter(used by filter)
+last-filter(used by filter)last
+location-filter(used by filter)location
+nth-filter(used by filter)
+regex-filter(used by filter)
+replace-filter(used by filter)
+replace-regex-filter(used by filter)
+split-filter(used by filter)
+to-date-filter(used by filter)
+to-float-filter(used by filter)toFloat
+to-hex-filter(used by filter)toHex
+to-int-filter(used by filter)toInt
+to-string-filter(used by filter)toString
+url-decode-filter(used by filter)urlDecode
+url-encode-filter(used by filter)urlEncode
+url-query-param-filter(used by filter)
+xpath-filter(used by filter)
+Lexical Grammar
boolean(used by boolean-option, variable-value, predicate-value, json-value)true|false
+null(used by variable-value, predicate-value, json-value)null
+alphanum(used by key-string-text)[A-Za-z0-9]
+integer(used by integer-option, duration-option, variable-value, nth-filter, float, number)
+float(used by variable-value, number)
+number(used by greater-predicate, greater-or-equal-predicate, less-predicate, less-or-equal-predicate, predicate-value)
+digit(used by json-integer, integer, fraction, exponent)[0-9]
+hexdigit(used by oneline-hex, unicode-char, json-string-escaped-char)[0-9A-Fa-f]
+fraction(used by json-number, float)
+exponent(used by json-number)
+sp(used by request, response, capture, assert, header-query, certificate-query, cookie-query, xpath-query, jsonpath-query, regex-query, variable-query, predicate, equal-predicate, not-equal-predicate, greater-predicate, greater-or-equal-predicate, less-predicate, less-or-equal-predicate, start-with-predicate, end-with-predicate, contain-predicate, match-predicate, include-predicate, expr, format-filter, jsonpath-filter, nth-filter, regex-filter, replace-filter, replace-regex-filter, split-filter, to-date-filter, url-query-param-filter, xpath-filter, lt)[ \t]
+lt(used by hurl-file, request, response, header, body, query-string-params-section, form-params-section, multipart-form-data-section, cookies-section, captures-section, asserts-section, basic-auth-section, options-section, filename-param, capture, assert, option, aws-sigv4-option, ca-certificate-option, client-certificate-option, client-key-option, compressed-option, connect-to-option, connect-timeout-option, delay-option, follow-redirect-option, follow-redirect-trusted-option, header-option, http10-option, http11-option, http2-option, http3-option, insecure-option, ipv4-option, ipv6-option, limit-rate-option, max-redirs-option, max-time-option, netrc-option, netrc-file-option, netrc-optional-option, output-option, path-as-is-option, pinned-public-key-option, proxy-option, resolve-option, repeat-option, retry-option, retry-interval-option, skip-option, unix-socket-option, user-option, variable-option, verbose-option, very-verbose-option, multiline-string)
+comment(used by lt)# ~[\n]*
+regex(used by regex-query, match-predicate, regex-filter, replace-regex-filter)
+regex-content(used by regex)
+regex-text(used by regex-content)~[\n\/]+
+regex-escaped-char(used by regex-content)\ ~[\n]
+
+
+
+
+
+# Resources {#resources}
+
+## License {#resources-license-license}
+
+```
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+Copyright 2021 Hurl
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+```
+
+
+
+
+
diff --git a/docs/standalone/hurl-7.0.0.pdf b/docs/standalone/hurl-7.0.0.pdf
new file mode 100644
index 0000000000..b6ba6fc2df
Binary files /dev/null and b/docs/standalone/hurl-7.0.0.pdf differ
diff --git a/packages/hurl/README.md b/packages/hurl/README.md
index d28d6112a1..c9010f2225 100644
--- a/packages/hurl/README.md
+++ b/packages/hurl/README.md
@@ -1758,9 +1758,9 @@ Please follow the [contrib on Windows section].
[GitHub]: https://github.com/Orange-OpenSource/hurl
[libcurl]: https://curl.se/libcurl/
[star Hurl on GitHub]: https://github.com/Orange-OpenSource/hurl/stargazers
-[HTML]: https://hurl.dev/assets/docs/hurl-6.1.0.html.gz
-[PDF]: https://hurl.dev/assets/docs/hurl-6.1.0.pdf.gz
-[Markdown]: https://hurl.dev/assets/docs/hurl-6.1.0.md.gz
+[HTML]: /docs/standalone/hurl-7.0.0.html
+[PDF]: /docs/standalone/hurl-7.0.0.pdf
+[Markdown]: https://hurl.dev/docs/standalone/hurl-7.0.0.html
[JSON body]: https://hurl.dev/docs/request.html#json-body
[XML body]: https://hurl.dev/docs/request.html#xml-body
[XML multiline string body]: https://hurl.dev/docs/request.html#multiline-string-body
+ +## Filters {#file-format-filters-filters} + +### Definition {#file-format-filters-definition} + +[Captures](#file-format-capturing-response) and [asserts](#file-format-asserting-response) share a common structure: query. A query is used to extract data from an HTTP response; this data +can come from the HTTP response body, the HTTP response headers or from the HTTP meta-information (like `duration` for instance)... + +In this example, the query __`jsonpath "$.books[0].name"`__ is used in a capture to save data and in an assert to test +the HTTP response body. + +__Capture__: + +
+ +## Templates {#file-format-templates-templates} + +### Variables {#file-format-templates-variables} + +In Hurl file, you can generate value using two curly braces, i.e `{{my_variable}}`. For instance, if you want to reuse a +value from an HTTP response in the next entries, you can capture this value in a variable and reuse it in a placeholder. + +In this example, we capture the value of a [CSRF token](https://en.wikipedia.org/wiki/Cross-site_request_forgery) from the body of the first response, and inject it +as a header in the next POST request: + +```hurl +GET https://example.org +HTTP 200 +[Captures] +csrf_token: xpath "string(//meta[@name='_csrf_token']/@content)" + +# Do the login ! +POST https://acmecorp.net/login?user=toto&password=1234 +X-CSRF-TOKEN: {{csrf_token}} +HTTP 302 +``` + +In this second example, we capture the body in a variable `index`, and reuse this value in the query +`jsonpath "$.errors[{{index}}].id"`: + + +```hurl +GET https://example.org/api/index +HTTP 200 +[Captures] +index: body + +GET https://example.org/api/status +HTTP 200 +[Asserts] +jsonpath "$.errors[{{index}}].id" == "error" +``` + + +### Functions {#file-format-templates-functions} + +Besides variables, functions can be used to generate dynamic values. Current functions are: + +| Function | Description | +|-------------|----------------------------------------------------------------| +| `newUuid` | Generates an [UUID v4 random string](https://en.wikipedia.org/wiki/Universally_unique_identifier) | +| `newDate` | Generates an [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339) UTC date string, at the current time | + +In the following example, we use `newDate` to generate a dynamic query parameter: + +```hurl +GET https://example.org/api/foo +[Query] +date: {{newDate}} +HTTP 200 +``` + +We run a `GET` request to `https://example.org/api/foo?date=2024%2D12%2D02T10%3A35%3A44%2E461731Z` where the `date` +query parameter value is `2024-12-02T10:35:44.461731Z` URL encoded. + +In this second example, we use `newUuid` function to generate an email dynamically: + +```hurl +POST https://example.org/api/foo +{ + "name": "foo", + "email": "{{newUuid}}@test.com" +} +``` + +When run, the request body will be: + +``` +{ + "name": "foo", + "email": "0531f78f-7f87-44be-a7f2-969a1c4e6d97@test.com" +} +``` + + +### Types {#file-format-templates-types} + +Values generated from function and variables are typed, and can be either string, bool, number, `null` or collections. Depending on the value type, +templates can be rendered differently. Let's say we have captured an integer value into a variable named +`count`: + +```hurl +GET https://sample/counter + +HTTP 200 +[Captures] +count: jsonpath "$.results[0]" +``` + +The following entry: + +```hurl +GET https://sample/counter/{{count}} + +HTTP 200 +[Asserts] +jsonpath "$.id" == "{{count}}" +``` + +will be rendered at runtime to: + +```hurl +GET https://sample/counter/458 + +HTTP 200 +[Asserts] +jsonpath "$.id" == "458" +``` + +resulting in a comparison between the [JSONPath](#file-format-asserting-response-jsonpath-assert) expression and a string value. + +On the other hand, the following assert: + +```hurl +GET https://sample/counter/{{count}} + +HTTP 200 +[Asserts] +jsonpath "$.index" == {{count}} +``` + +will be rendered at runtime to: + +```hurl +GET https://sample/counter/458 + +HTTP 200 +[Asserts] +jsonpath "$.index" == 458 +``` + +resulting in a comparison between the [JSONPath](#file-format-asserting-response-jsonpath-assert) expression and an integer value. + +So if you want to use typed values (in asserts for instances), you can use `{{my_var}}`. +If you're interested in the string representation of a variable, you can surround the variable with double quotes +, as in `"{{my_var}}"`. + +> When there is no possible ambiguities, like using a variable in an URL, or +> in a header, you can omit the double quotes. The value will always be rendered +> as a string. + +### Injecting Variables {#file-format-templates-injecting-variables} + +Variables can be injected in a Hurl file: + +- by using [`--variable` option](#getting-started-manual-variable) +- by using [`--variables-file` option](#getting-started-manual-variables-file) +- by defining environment variables, for instance `HURL_foo=bar` +- by defining variables in an [`[Options]` section][options](#file-format-request-options) + +Lets' see how to inject variables, given this `test.hurl`: + +```hurl +GET https://{{host}}/{{id}}/status +HTTP 304 + +GET https://{{host}}/health +HTTP 200 +``` + +#### `variable` option {#file-format-templates-variable-option} + +Variable can be defined with command line option: + +```shell +$ hurl --variable host=example.net --variable id=1234 test.hurl +``` + + +#### `variables-file` option {#file-format-templates-variables-file-option} + +We can also define all injected variables in a file: + +```shell +$ hurl --variables-file vars.env test.hurl +``` + +where `vars.env` is + +``` +host=example.net +id=1234 +``` + +#### Environment variable {#file-format-templates-environment-variable} + +We can use environment variables in the form of `HURL_name=value`: + +```shell +$ export HURL_host=example.net +$ export HURL_id=1234 +$ hurl test.hurl +``` + +#### Options sections {#file-format-templates-options-sections} + +We can define variables in `[Options]` section. Variables defined in a section are available for the next requests. + +```hurl +GET https://{{host}}/{{id}}/status +[Options] +variable: host=example.net +variable: id=1234 +HTTP 304 + +GET https://{{host}}/health +HTTP 200 +``` + +#### Secrets {#file-format-templates-secrets} + +Secrets are variables which value is redacted from standard error logs (for instance using [`--very-verbose`](#getting-started-manual-very-verbose)) and [reports](#getting-started-running-tests-generating-report). +Secrets are injected through command-line with [`--secret` option](#getting-started-manual-secret): + +```shell +$ hurl --secret token=FooBar test.hurl +``` + +Values are redacted by _exact matching_: if a secret value is transformed, and you want to redact also the transformed value, +you can add as many secrets as there are transformed values. Even if a secret is not used as a variable, all secrets values +will be redacted from messages and logs. + +```shell +$ hurl --secret token=FooBar \ + --secret token_alt_0=FOOBAR \ + --secret token_alt_1=foobar \ + test.hurl +``` + +> Secrets __are not redacted__ from HTTP responses outputted on standard output as Hurl considers the standard output as +> the correct unaltered output of a run. With this call `$ hurl --secret token=FooBar test.hurl`, +> the HTTP response is outputted unaltered and `FooBar` can appear in the HTTP response. Options that transforms Hurl +> output on standard output, like [`--include`](#getting-started-manual-include) or [`--json`](#getting-started-manual-json) works the same. [JSON report](#getting-started-running-tests-json-report) also saves each unaltered HTTP +> response on disk so extra care must be taken when secrets are in the HTTP response body. + + +### Templating Body {#file-format-templates-templating-body} + +Variables and functions can be used in [JSON body](#file-format-request-json-body): + +~~~hurl +PUT https://example.org/api/hits +{ + "key0": "{{a_string}}", + "key1": {{a_bool}}, + "key2": {{a_null}}, + "key3": {{a_number}}, + "key4": "{{newDate}}" +} +~~~ + +Note that we're writing a kind of JSON body directly without any delimitation marker. For the moment, [XML body](#file-format-request-xml-body) can't +use variables directly. In order to templatize a XML body, you can use [multiline string body](#file-format-request-multiline-string-body) with variables and +functions. The multiline string body allows to templatize any text based body (JSON, XML, CSV etc...): + +Multiline string body delimited by `` ``` ``: + +~~~hurl +PUT https://example.org/api/hits +Content-Type: application/json +``` +{ + "key0": "{{a_string}}", + "key1": {{a_bool}}, + "key2": {{a_null}}, + "key3": {{a_number}}, + "key4: "{{newDate}}" +} +``` +~~~ + +Variables can be initialized via command line: + +```shell +$ hurl --variable a_string=apple --variable a_bool=true --variable a_null=null --variable a_number=42 test.hurl +``` + +Resulting in a PUT request with the following JSON body: + +``` +{ + "key0": "apple", + "key1": true, + "key2": null, + "key3": 42, + "key4": "2024-12-02T13:39:45.936643Z" +} +``` + + + +
+ +## Grammar {#file-format-grammar-grammar} + +### Definitions {#file-format-grammar-definitions} + +Short description: + +- operator | denotes alternative, +- operator * denotes iteration (zero or more), +- operator + denotes iteration (one or more), + +### Syntax Grammar {#file-format-grammar-syntax-grammar} + +
General
+ ++|HTTP/1.1
+|HTTP/2
+|HTTP
Sections
+(aws-sigv4-option|ca-certificate-option|client-certificate-option|client-key-option|compressed-option|connect-to-option|connect-timeout-option|delay-option|follow-redirect-option|follow-redirect-trusted-option|header-option|http10-option|http11-option|http2-option|http3-option|insecure-option|ipv4-option|ipv6-option|limit-rate-option|max-redirs-option|max-time-option|netrc-option|netrc-file-option|netrc-optional-option|output-option|path-as-is-option|pinned-public-key-option|proxy-option|repeat-option|resolve-option|retry-option|retry-interval-option|skip-option|unix-socket-option|user-option|variable-option|verbose-option|very-verbose-option)
Query
Predicates
+|not-equal-predicate
+|greater-predicate
+|greater-or-equal-predicate
+|less-predicate
+|less-or-equal-predicate
+|start-with-predicate
+|end-with-predicate
+|contain-predicate
+|match-predicate
+|exist-predicate
+|is-empty-predicate
+|include-predicate
+|integer-predicate
+|float-predicate
+|boolean-predicate
+|string-predicate
+|collection-predicate
+|date-predicate
+|iso-date-predicate
+|is-ipv4-predicate
+|is-ipv6-predicate
+|is-uuid-predicate
+|multiline-string
+|null
+|number
+|oneline-string
+|oneline-base64
+|oneline-file
+|oneline-hex
+|quoted-string
+|placeholder
Bytes
Strings
+(multiline-string-content|placeholder)* lt
+```
+|hex
+|json
+|xml
+|graphql
+|novariable
JSON
Expression
Function
Filter
+|base64-encode-filter
+|base64-url-safe-decode-filter
+|base64-url-safe-encode-filter
+|count-filter
+|days-after-now-filter
+|days-before-now-filter
+|decode-filter
+|first-filter
+|format-filter
+|html-escape-filter
+|html-unescape-filter
+|jsonpath-filter
+|last-filter
+|location-filter
+|nth-filter
+|regex-filter
+|replace-filter
+|replace-regex-filter
+|split-filter
+|to-date-filter
+|to-float-filter
+|to-hex-filter
+|to-int-filter
+|to-string-filter
+|url-decode-filter
+|url-encode-filter
+|url-query-param-filter
+|xpath-filter
Lexical Grammar
+ +# Resources {#resources} + +## License {#resources-license-license} + +``` + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright 2021 Hurl + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +``` + + +
+ + diff --git a/docs/standalone/hurl-7.0.0.pdf b/docs/standalone/hurl-7.0.0.pdf new file mode 100644 index 0000000000..b6ba6fc2df Binary files /dev/null and b/docs/standalone/hurl-7.0.0.pdf differ diff --git a/packages/hurl/README.md b/packages/hurl/README.md index d28d6112a1..c9010f2225 100644 --- a/packages/hurl/README.md +++ b/packages/hurl/README.md @@ -1758,9 +1758,9 @@ Please follow the [contrib on Windows section]. [GitHub]: https://github.com/Orange-OpenSource/hurl [libcurl]: https://curl.se/libcurl/ [star Hurl on GitHub]: https://github.com/Orange-OpenSource/hurl/stargazers -[HTML]: https://hurl.dev/assets/docs/hurl-6.1.0.html.gz -[PDF]: https://hurl.dev/assets/docs/hurl-6.1.0.pdf.gz -[Markdown]: https://hurl.dev/assets/docs/hurl-6.1.0.md.gz +[HTML]: /docs/standalone/hurl-7.0.0.html +[PDF]: /docs/standalone/hurl-7.0.0.pdf +[Markdown]: https://hurl.dev/docs/standalone/hurl-7.0.0.html [JSON body]: https://hurl.dev/docs/request.html#json-body [XML body]: https://hurl.dev/docs/request.html#xml-body [XML multiline string body]: https://hurl.dev/docs/request.html#multiline-string-body
+
+
+
+