Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for CORS #16

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 51 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
smoke.sh
========
# smoke.sh

A minimal smoke testing framework in Bash.

Expand All @@ -8,14 +7,14 @@ Features:
- Response body checks
- Response code checks
- Response header checks
- GET/POST on endpoints
- GET/POST/OPTIONS on endpoints
- ORIGIN support for testing CORS responses
- CSRF tokens
- Reporting and sane exit codes

![smoke sh](https://f.cloud.github.com/assets/657357/1238166/6f47f56a-29e4-11e3-9e19-394ca12b5fd0.png)

Example
-------
## Example

Checking if the Google Search home page works and contains the word "search":

Expand All @@ -33,16 +32,15 @@ Running:

```bash
$ ./smoke-google
> http://google.com/
> GET http://google.com/
[ OK ] 2xx Response code
[ OK ] Body contains "search"
OK (2/2)
```

For a more advanced and complete example, see below.

Setup and usage
--------------
## Setup and usage

The recommended setup includes copying the `smoke.sh` file in the appropriate
place and creating a new file in the same directory that you will write your
Expand Down Expand Up @@ -88,6 +86,7 @@ smoke_form_ok "http://example.org/login" path/to/postdata
```

And the POST data (`path/to/postdata`):

```
username=smoke&password=test
```
Expand Down Expand Up @@ -125,27 +124,44 @@ smoke_url_ok "/login"

If the server requires a certain host header to be set, override the host from the URL with

```
```bash
smoke_host "example.org"
```

To un-override, set it empty:

```
```bash
smoke_host ""
```

### Overriding request headers

It's possible to set additional request headers, like `X-Forwarded-Proto` for local tests.

```
```bash
smoke_header "X-Forwarded-Host: orginal.example.org"
smoke_header "X-Forwarded-Proto: https"
```

Existing custom headers can be unset with `remove_smoke_headers`.

### Checking CORS is enabled for a certain Origin

First of all, set the origin header with:

```bash
smoke_origin "https://acme.corp"
```

Then test for CORS headers using:

```bash
smoke_url_cors "https://api.com/endpoint" "POST,GET"
smoke_assert_headers "Access-Control-Allow-Credentials: true"
smoke_assert_headers "Access-Control-Allow-Methods: POST,GET"
smoke_assert_headers "Access-Control-Allow-Origin: https://acme.corp"
```

### CSRF tokens

Web applications that are protected with CSRF tokens will need to extract a
Expand Down Expand Up @@ -185,8 +201,7 @@ smoke_response_body # raw body (html/json/...)
smoke_response_headers # list of headers
```

Advanced example
----------------
## Advanced example

More advanced example showing all features of `smoke.sh`:

Expand Down Expand Up @@ -226,25 +241,26 @@ smoke_form_ok "/login" postdata/login
smoke_report
```

API
---

| function | description |
|---------------------------------|------------------------------------------------------|
|`smoke_assert_body <string>` | assert that the body contains `<string>` |
|`smoke_assert_code <code>` | assert that there was a `<code>` response code |
|`smoke_assert_code_ok` | assert that there was a `2xx` response code |
|`smoke_assert_headers <string>` | assert that the headers contain `<string>` |
|`smoke_csrf <token>` | set the csrf token to use in POST requests |
|`smoke_form <url> <datafile>` | POST data on url |
|`smoke_form_ok <url> <datafile>` | POST data on url and check for a `2xx` response code |
|`smoke_report` | prints the report and exits |
|`smoke_response_body` | body of the last response |
|`smoke_response_code` | code of the last response |
|`smoke_response_headers` | headers of the last response |
|`smoke_url <url>` | GET a url |
|`smoke_url_ok <url>` | GET a url and check for a `2xx` response code |
|`smoke_url_prefix <prefix>` | set the prefix to use for every url (e.g. domain) |
|`smoke_host <host>` | set the host header to use |
|`smoke_header <header>` | set additional request header |
|`smoke_tcp_ok <host> <port>` | open a tcp connection and check for a `Connected` response |
## API

| function | description |
| -------------------------------- | ---------------------------------------------------------- |
| `smoke_assert_body <string>` | assert that the body contains `<string>` |
| `smoke_assert_code <code>` | assert that there was a `<code>` response code |
| `smoke_assert_code_ok` | assert that there was a `2xx` response code |
| `smoke_assert_headers <string>` | assert that the headers contain `<string>` |
| `smoke_csrf <token>` | set the csrf token to use in POST requests |
| `smoke_form <url> <datafile>` | POST data on url |
| `smoke_form_ok <url> <datafile>` | POST data on url and check for a `2xx` response code |
| `smoke_origin <origin>` | sets the `Origin` header |
| `smoke_report` | prints the report and exits |
| `smoke_response_body` | body of the last response |
| `smoke_response_code` | code of the last response |
| `smoke_response_headers` | headers of the last response |
| `smoke_url <url>` | GET a url |
| `smoke_url_cors <url>` | Check CORS via OPTIONS verb |
| `smoke_url_ok <url>` | GET a url and check for a `2xx` response code |
| `smoke_url_prefix <prefix>` | set the prefix to use for every url (e.g. domain) |
| `smoke_host <host>` | set the host header to use |
| `smoke_header <header>` | set additional request header |
| `smoke_tcp_ok <host> <port>` | open a tcp connection and check for a `Connected` response |
46 changes: 40 additions & 6 deletions smoke.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,19 @@ SMOKE_TESTS_FAILED=0
SMOKE_TESTS_RUN=0
SMOKE_URL_PREFIX=""
SMOKE_HEADERS=()
SMOKE_HEADER_HOST=""
SMOKE_ORIGIN=""

## "Public API"

smoke_csrf() {
SMOKE_CSRF_TOKEN="$1"
}

smoke_origin() {
SMOKE_ORIGIN="$1"
}

smoke_form() {
URL="$1"
FORMDATA="$2"
Expand Down Expand Up @@ -66,7 +72,7 @@ smoke_response_headers() {

smoke_tcp_ok() {
URL="$1 $2"
_smoke_print_url "$URL"
_smoke_print_url "TCP" "$URL"
echo EOF | telnet $URL > $SMOKE_CURL_BODY
smoke_assert_body "Connected"
}
Expand All @@ -76,6 +82,13 @@ smoke_url() {
_curl_get $URL
}

smoke_url_cors() {
URL="$1"
SMOKE_CORS_METHOD="$2"
_curl_options $URL
SMOKE_CORS_METHOD=""
}

smoke_url_ok() {
URL="$1"
smoke_url "$URL"
Expand Down Expand Up @@ -189,15 +202,22 @@ _curl() {
opt+=(-H "$header")
done
fi

if [[ -n "$SMOKE_ORIGIN" ]]
then
opt+=(-H "Origin: $SMOKE_ORIGIN")
fi
if [[ -n "$SMOKE_CORS_METHOD" ]]
then
opt+=(-H "access-control-request-method: $SMOKE_CORS_METHOD")
fi
curl "${opt[@]}" "$@" > $SMOKE_CURL_BODY
}

_curl_get() {
URL="$1"

SMOKE_URL="$SMOKE_URL_PREFIX$URL"
_smoke_print_url "$SMOKE_URL"
_smoke_print_url "GET" "$SMOKE_URL"

_curl $SMOKE_URL

Expand All @@ -206,13 +226,26 @@ _curl_get() {
$SMOKE_AFTER_RESPONSE
}

_curl_options() {
URL="$1"

SMOKE_URL="$SMOKE_URL_PREFIX$URL"
_smoke_print_url "OPTIONS" "$SMOKE_URL"

_curl -X OPTIONS $SMOKE_URL

grep -oE 'HTTP[^ ]+ [0-9]{3}' $SMOKE_CURL_HEADERS | tail -n1 | grep -oE '[0-9]{3}' > $SMOKE_CURL_CODE

$SMOKE_AFTER_RESPONSE
}

_curl_post() {
URL="$1"
FORMDATA="$2"
FORMDATA_FILE="@"$(_smoke_prepare_formdata $FORMDATA)

SMOKE_URL="$SMOKE_URL_PREFIX$URL"
_smoke_print_url "$SMOKE_URL"
_smoke_print_url "POST" "$SMOKE_URL"

_curl --data "$FORMDATA_FILE" $SMOKE_URL

Expand Down Expand Up @@ -257,6 +290,7 @@ _smoke_print_success() {
}

_smoke_print_url() {
TEXT="$1"
echo "> $TEXT"
VERB="$1"
URL="$2"
echo "> ${VERB} ${bold}${URL}${normal}"
}