hurl/docs/tutorial/debug-tips.md
2023-01-25 11:26:30 +01:00

458 lines
14 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Debug Tips
Now that we have many requests in our test file, let's review some tips on how to debug the executed HTTP exchanges.
## Verbose Mode
### Using --verbose and --very-verbose for all entries
We can run our test with [`-v/--verbose` option]. In this mode, each entry is displayed with debugging
information like request HTTP headers, response HTTP headers, cookie storage, duration etc...
```shell
$ hurl --verbose --no-output basic.hurl
* Options:
* fail fast: true
* insecure: false
* follow redirect: false
* max redirect: 50
* ------------------------------------------------------------------------------
* Executing entry 1
*
* Cookie store:
*
* Request:
* GET http://localhost:8080
*
* Request can be run with the following curl command:
* curl 'http://localhost:8080'
*
> GET / HTTP/1.1
> Host: localhost:8080
> Accept: */*
> User-Agent: hurl/1.7.0-snapshot
>
* Response:
*
< HTTP/1.1 200
< Set-Cookie: JSESSIONID=361948EF00AA04CB6659954A8D3EBC9D; Path=/; HttpOnly
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Content-Type: text/html;charset=UTF-8
< Content-Language: en-FR
< Transfer-Encoding: chunked
< Date: Wed, 17 Aug 2022 07:30:15 GMT
<
*
* ------------------------------------------------------------------------------
* Executing entry 2
*
* Cookie store:
* #HttpOnly_localhost FALSE / FALSE 0 JSESSIONID 361948EF00AA04CB6659954A8D3EBC9D
*
* Request:
* GET http://localhost:8080/not-found
*
* Request can be run with the following curl command:
* curl 'http://localhost:8080/not-found' --cookie 'JSESSIONID=361948EF00AA04CB6659954A8D3EBC9D'
*
> GET /not-found HTTP/1.1
> Host: localhost:8080
> Accept: */*
> Cookie: JSESSIONID=361948EF00AA04CB6659954A8D3EBC9D
> User-Agent: hurl/1.7.0-snapshot
>
* Response:
*
< HTTP/1.1 404
< Vary: Origin
< Vary: Access-Control-Request-Method
< Vary: Access-Control-Request-Headers
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Content-Type: text/html;charset=UTF-8
< Content-Language: en-FR
< Transfer-Encoding: chunked
< Date: Wed, 17 Aug 2022 07:30:15 GMT
<
*
...
```
Lines beginning with `*` are debug info, lines that begin with `>` are HTTP request headers and lines that begin with
`<` are HTTP response headers.
In verbose mode, HTTP request and response bodies are not displayed in the debug logs. If you need to inspect the
request or response body, you can display more logs with [`--very-verbose`] option:
```shell
$ hurl --very-verbose --no-output basic.hurl
* Options:
* fail fast: true
* insecure: false
* follow redirect: false
* max redirect: 50
* ------------------------------------------------------------------------------
* Executing entry 1
*
* Cookie store:
*
* Request:
* GET http://localhost:8080
*
* Request can be run with the following curl command:
* curl 'http://localhost:8080'
*
> GET / HTTP/1.1
> Host: localhost:8080
> Accept: */*
> User-Agent: hurl/1.7.0-snapshot
>
* Request body:
*
* Response:
*
< HTTP/1.1 200
< Set-Cookie: JSESSIONID=0B417BD5890C001B5B25A9B321FE4800; Path=/; HttpOnly
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Content-Type: text/html;charset=UTF-8
< Content-Language: en-FR
< Transfer-Encoding: chunked
< Date: Wed, 17 Aug 2022 07:42:46 GMT
<
* Response body:
* <!doctype html>
* <html lang="en">
* <head>
* <meta charset="UTF-8" />
* <meta name="viewport" content="width=device-width, initial-scale=1.0" />
* <title>Welcome to Quiz!</title>
* <link rel="stylesheet" href="/style.css">
* <!--<script src="script.js"></script>-->
* </head>
* <body>
* <div>
...
* </body>
* </html>
*
*
* ------------------------------------------------------------------------------
* Executing entry 2
*
* Cookie store:
* #HttpOnly_localhost FALSE / FALSE 0 JSESSIONID 0B417BD5890C001B5B25A9B321FE4800
*
* Request:
* GET http://localhost:8080/not-found
*
* Request can be run with the following curl command:
* curl 'http://localhost:8080/not-found' --cookie 'JSESSIONID=0B417BD5890C001B5B25A9B321FE4800'
*
> GET /not-found HTTP/1.1
> Host: localhost:8080
> Accept: */*
> Cookie: JSESSIONID=0B417BD5890C001B5B25A9B321FE4800
> User-Agent: hurl/1.7.0-snapshot
>
* Request body:
*
* Response:
*
< HTTP/1.1 404
< Vary: Origin
< Vary: Access-Control-Request-Method
< Vary: Access-Control-Request-Headers
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Content-Type: text/html;charset=UTF-8
< Content-Language: en-FR
< Transfer-Encoding: chunked
< Date: Wed, 17 Aug 2022 07:42:46 GMT
<
* Response body:
* <!doctype html>
* <html lang="en">
* <head>
* <meta charset="UTF-8" />
* <meta name="viewport" content="width=device-width, initial-scale=1.0" />
* <title>Error 404 - Quiz</title>
* <link rel="stylesheet" href="/style.css">
* <!--<script src="script.js"></script>-->
* </head>
* <body>
* <div>
* <a href="/"><img class="logo-img" src="/quiz.svg" alt="Quiz logo"></a>
* </div>
* <div class="main">
*
* <h1>Error 404, Page not Found!</h1>
*
...
* </body>
* </html>
*
*
...
```
### Debugging a specific entry
If you have a lot of entries (request / response pairs) in your Hurl file, using [`--verbose`] or [`--very-verbose`]
can produce a lot of logs and can be difficult to analyse. Instead of passing options to the command line, you can
use an `[Options]` section that will activate logs only for the specified entry:
```hurl
# Checking our home page:
# ...
# Check that we have a 404 response for broken links:
# ...
# Check our health API:
# ...
# Check question API:
GET http://localhost:8080/api/questions
# You can pass options to this entry only
[Options]
verbose: true
[QueryStringParams]
offset: 0
size: 20
sort: oldest
HTTP 200
# ...
```
And run it without [`--verbose`] option:
```shell
$ hurl --no-output basic.hurl
* ------------------------------------------------------------------------------
* Executing entry 4
*
* Entry options:
* verbose: true
*
* Cookie store:
* #HttpOnly_localhost FALSE / FALSE 0 JSESSIONID 31818147FB20A7085AC54C372318BAF1
*
* Request:
* GET http://localhost:8080/api/questions
* [QueryStringParams]
* offset: 0
* size: 20
* sort: oldest
*
* Request can be run with the following curl command:
* curl 'http://localhost:8080/api/questions?offset=0&size=20&sort=oldest' --cookie 'JSESSIONID=31818147FB20A7085AC54C372318BAF1'
*
> GET /api/questions?offset=0&size=20&sort=oldest HTTP/1.1
> Host: localhost:8080
> Accept: */*
> Cookie: JSESSIONID=31818147FB20A7085AC54C372318BAF1
> User-Agent: hurl/1.7.0-snapshot
>
* Response:
*
< HTTP/1.1 200
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Content-Type: application/json
< Transfer-Encoding: chunked
< Date: Wed, 17 Aug 2022 08:11:50 GMT
<
*
```
## Interactive Mode
We can run the whole Hurl file request by request, with the [`--interactive` option]:
```shell
* Options:
* fail fast: true
* insecure: false
* follow redirect: false
* max redirect: 50
Interactive mode:
Next request:
GET http://localhost:8080
Press Q (Quit) or C (Continue)
* ------------------------------------------------------------------------------
* Executing entry 1
*
* Cookie store:
*
* Request:
* GET http://localhost:8080
*
* Request can be run with the following curl command:
* curl 'http://localhost:8080'
*
> GET / HTTP/1.1
> Host: localhost:8080
> Accept: */*
> User-Agent: hurl/1.7.0-snapshot
>
* Response:
*
< HTTP/1.1 200
< Set-Cookie: JSESSIONID=B08BF0F6F83E91750A76E97713A5C144; Path=/; HttpOnly
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Content-Type: text/html;charset=UTF-8
< Content-Language: en-FR
< Transfer-Encoding: chunked
< Date: Wed, 17 Aug 2022 08:18:36 GMT
<
*
Interactive mode:
Next request:
GET http://localhost:8080/not-found
Press Q (Quit) or C (Continue)
```
## Include Headers Like curl
We can also run our file to only output HTTP headers, with [`-i/--include` option].
In this mode, headers of the last entry are displayed:
```shell
$ hurl -i basic.hurl
HTTP/1.1 200
Set-Cookie: JSESSIONID=76984131F0D0821C4A8D5CB3FC27CD3B; Path=/; HttpOnly
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/json
Transfer-Encoding: chunked
Date: Fri, 13 Jan 2023 12:49:47 GMT
{"status":"RUNNING","reportedDate":"2023-01-13T13:49:47+01:00","healthy":true,"operationId":3183000623}
```
If you want to inspect any entry other than the last one, you can run your test to a
given entry with the [`--to-entry` option], starting at index 1:
```shell
$ hurl -i --to-entry 2 basic.hurl
HTTP/1.1 404
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: text/html;charset=UTF-8
Content-Language: en-FR
Transfer-Encoding: chunked
Date: Fri, 13 Jan 2023 12:50:52 GMT
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Error 404 - Quiz</title>
<link rel="stylesheet" href="/style.css">
<!--<script src="script.js"></script>-->
</head>
<body>
<div>
<a href="/"><img class="logo-img" src="/quiz.svg" alt="Quiz logo"></a>
</div>
<div class="main">
<h1>Error 404, Page not Found!</h1>
<a href="/">Quiz Home</a>
</div>
<footer>
<div class="footer">
<div class="footer-body">a game by <a href="https://hurl.dev">Hurl&RightArrowLeftArrow; Team</a></div>
</div>
</footer>
</body>
</html>
```
## Using a Proxy
Finally, you can use a proxy between Hurl and your server to inspect requests and responses.
For instance, with [mitmproxy]:
1. First, launch mitmproxy, it will listen to connections on 8888 port
```shell
$ mitmweb -p 8888 --web-port 8889 --web-open-browser
Web server listening at http://127.0.0.1:8889/
Proxy server listening at http://*:8888
```
2. Then, run Hurl with [`-x/--proxy` option]
```shell
$ hurl --proxy localhost:8888 basic.hurl
```
The web interface of mitmproxy allows you to inspect, intercept any requests run by Hurl, and see
the returned response to Hurl.
[`-v/--verbose` option]: /docs/manual.md#verbose
[`--very-verbose`]: /docs/manual.md#very-verbose
[`--verbose`]: /docs/manual.md#verbose
[`--interactive` option]: /docs/manual.md#interactive
[`-i/--include` option]: /docs/manual.md#include
[`--to-entry` option]: /docs/manual.md#to-entry
[mitmproxy]: https://mitmproxy.org
[`-x/--proxy` option]: /docs/manual.md#proxy