Skip to content

Commit

Permalink
Merge pull request #8 from phymbert/hp/headers-support
Browse files Browse the repository at this point in the history
fix request headers not passed
  • Loading branch information
phymbert authored Apr 19, 2024
2 parents f315a8a + d09858f commit 840c739
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 46 deletions.
50 changes: 29 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
# xk6-sse
A [k6](https://go.k6.io/k6) extension for [Server-Sent Events (SSE)](https://en.wikipedia.org/wiki/Server-sent_events) using the [xk6](https://github.com/grafana/xk6) system.


| /!\ This is a proof of concept, isn't supported by the k6 team, and may break in the future. USE AT YOUR OWN RISK! |
|--------------------------------------------------------------------------------------------------------------------|

See the [K6 SSE Extension design](docs/design/021-sse-api.md).

## k6 version
Expand Down Expand Up @@ -36,30 +32,42 @@ xk6 build master \
## Example

```javascript
import sse from "k6/x/sse";
import {check} from "k6";
import sse from "k6/x/sse"
import {check} from "k6"

export default function () {
var url = "https://echo.websocket.org/.sse";
var params = {"tags": {"my_tag": "hello"}};

var response = sse.open(url, params, function (client) {
const url = "https://echo.websocket.org/.sse"
const params = {
method: 'GET',
headers: {
"Authorization": "Bearer XXXX"
},
tags: {"my_k6s_tag": "hello sse"}
}

const response = sse.open(url, params, function (client) {
client.on('open', function open() {
console.log('connected');
});
console.log('connected')
})

client.on('event', function (event) {
console.log(`event id=${event.id}, name=${event.name}, data=${event.data}`);
if (parseInt(event.id) === 10) {
client.close();
console.log(`event id=${event.id}, name=${event.name}, data=${event.data}`)
if (parseInt(event.id) === 4) {
client.close()
}
});
})

client.on('error', function (e) {
console.log('An unexpected error occurred: ', e.error());
});
});
console.log('An unexpected error occurred: ', e.error())
})
})

check(response, {"status is 200": (r) => r && r.status === 200});
};
check(response, {"status is 200": (r) => r && r.status === 200})
}
```

### License

Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
46 changes: 26 additions & 20 deletions examples/sse.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@
import sse from "k6/x/sse";
import {check} from "k6";
import sse from "k6/x/sse"
import {check} from "k6"

export default function () {
var url = "https://echo.websocket.org/.sse";
var params = {"tags": {"my_tag": "hello"}};
const url = "https://echo.websocket.org/.sse"
const params = {
method: 'GET',
headers: {
"Authorization": "Bearer XXXX"
},
tags: {"my_k6s_tag": "hello sse"}
}

var response = sse.open(url, params, function (client) {
client.on('open', function open() {
console.log('connected');
});
const response = sse.open(url, params, function (client) {
client.on('open', function open() {
console.log('connected')
})

client.on('event', function (event) {
console.log(`event id=${event.id}, name=${event.name}, data=${event.data}`);
if (parseInt(event.id) === 10) {
client.close();
}
});
client.on('event', function (event) {
console.log(`event id=${event.id}, name=${event.name}, data=${event.data}`)
if (parseInt(event.id) === 4) {
client.close()
}
})

client.on('error', function (e) {
console.log('An unexpected error occurred: ', e.error());
});
});
client.on('error', function (e) {
console.log('An unexpected error occurred: ', e.error())
})
})

check(response, {"status is 200": (r) => r && r.status === 200});
};
check(response, {"status is 200": (r) => r && r.status === 200})
}
25 changes: 25 additions & 0 deletions examples/sse_post.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import sse from "k6/x/sse";
import {check} from "k6";

export default function () {
const url = "https://echo.websocket.org/.sse";
const params = {
method: 'POST',
body: '{"ping": true}',
headers: {
"content-type": "application/json",
"Authorization": "Bearer XXXX"
}
}

const response = sse.open(url, params, function (client) {
client.on('event', function (event) {
console.log(`event id=${event.id}, name=${event.name}, data=${event.data}`);
if (parseInt(event.id) === 2) {
client.close()
}
})
})

check(response, {"status is 200": (r) => r && r.status === 200})
}
7 changes: 5 additions & 2 deletions sse.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,9 +210,12 @@ func (mi *sse) open(ctx context.Context, state *lib.State,
return &sseClient, nil, err
}

req.Header.Set("Cache-Control", "no-cache")
req.Header.Set("Accept", "text/event-stream")
req.Header.Set("Connection", "keep-alive")
for headerName, headerValues := range args.headers {
for _, headerValue := range headerValues {
req.Header.Set(headerName, headerValue)
}
}

// Wrap the request to retrieve the server IP tag
trace := &httptrace.ClientTrace{
Expand Down
7 changes: 5 additions & 2 deletions sse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ func TestOpen(t *testing.T) {
sr := test.tb.Replacer.Replace
_, err := test.VU.Runtime().RunString(sr(`
var events = [];
var res = sse.open("HTTPBIN_IP_URL/sse", {method: 'POST', body: '{"ping": true}'}, function(client){
var res = sse.open("HTTPBIN_IP_URL/sse", {method: 'POST', body: '{"ping": true}', headers: {"content-type": "application/json", "Authorization": "Bearer XXXX"}}, function(client){
client.on("event", function(event) {
events.push(event);
});
Expand Down Expand Up @@ -293,7 +293,7 @@ func TestUserAgent(t *testing.T) {
if (userAgent == undefined) {
throw new Error("user agent is not echoed back by test server");
}
if (userAgent != "Go-http-client/1.1") {
if (userAgent != "TestUserAgent") {
throw new Error("incorrect user agent: " + userAgent);
}
`))
Expand Down Expand Up @@ -392,6 +392,9 @@ func sseHandler(t testing.TB, generateErrors bool) http.Handler {
_, _ = w.Write([]byte("junk\n"))
} else {
if req.Method == http.MethodPost {
assert.Equal(t, "application/json", req.Header.Get("Content-Type"))
assert.Equal(t, "Bearer XXXX", req.Header.Get("Authorization"))

body, err := io.ReadAll(req.Body)
require.NoError(t, err)
if `{"ping": true}` != string(body) {
Expand Down
8 changes: 7 additions & 1 deletion tests.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
#!/bin/bash

xk6 build --with github.com/phymbert/xk6-sse=. && ./k6 run --vus 5 --duration 10s examples/sse.js
set -eux

xk6 build --with github.com/phymbert/xk6-sse=.
for script in examples/*
do
./k6 run --vus 5 --duration 10s "${script}"
done

0 comments on commit 840c739

Please sign in to comment.