k6 v0.25.0 is here! :tada:

This release contains mostly bug fixes, though it also has a few new features, enhancements, and performance improvements. These include HTTP request compression, `brotli` and `zstd` support, massive VU RAM usage and initialization time decreases, support for importing files via `https` and `file` URLs, and opt-in TLS 1.3 support.

Thanks to @THoelzel, @matlockx, @bookmoons, @cuonglm, and @imiric for contributing to this release!

## New features and enhancements!

### HTTP: request body compression + brotli and zstd decompression (#989, #1082)

Now k6 can compress the body of any HTTP request before sending it (#989). That can be enabled by setting the new `compression` option in the [`http.Params` object](https://docs.k6.io/docs/params-k6http). Doing so will cause k6 to transparently compress the supplied request body and correctly set both `Content-Encoding` and `Content-Length`, unless they were manually set in the request `headers` by the user. The currently supported algorithms are `deflate`, `gzip`, `brotli` and `zstd`, as well as any combination of them separated by commas (`,`).

k6 now also transparently decompresses `brotli` and `zstd` HTTP responses - previously only `deflate` and `gzip` were supported. Thanks, @imiric! (#1082)

```js
import http from 'k6/http';
import { check } from "k6";

export default function () {
    // Test gzip compression
    let gzippedReqResp = http.post("https://httpbin.org/post", "foobar".repeat(1000), { compression: "gzip" });
    check(gzippedReqResp, {
        "request gzip content-encoding": (r) => r.json().headers["Content-Encoding"] === "gzip",
        "actually compressed body": (r) => r.json().data.length < 200,
    });

    // Test br decompression
    let brotliResp = http.get("https://httpbin.org/brotli", {
        headers: {
            "Accept-Encoding": "gzip, deflate, br"
        },
    });
    check(brotliResp, {
        "br content-encoding header": (r) => r.headers["Content-Encoding"] === "br",
        "br confirmed in body": (r) => r.json().brotli === true,
    });

    // Test zstd decompression
    let zstdResp = http.get("https://facebook.com/", {
        headers: {
            "Accept-Encoding": "zstd"
        },
    });
    check(zstdResp, {
        "zstd content-encoding header": (r) => r.headers["Content-Encoding"] === "zstd",
        "readable HTML in body": (r) => r.body.includes("html"),
    });
};
```

### Performance improvement: reuse the parsed core-js library across VUs (#1038)

k6 uses the awesome [core-js](https://github.com/zloirock/core-js) library to support new JavaScript features. It is included as a polyfill in each VU (i.e. JS runtime) and previously, it was parsed anew for every VU initialization. Now, the parsing result is cached after the first time and shared between VUs, leading to over **2x reduction of VU memory usage and initialization times** for simple scripts!

Thanks, @matlockx, for noticing this opportunity for massive optimization!

### JS files can now be imported via `https` and `file` URLs (#1059)

Previously, k6 had a mechanism for importing files via HTTPS URLs, but required that the used URLs not contain the `https` scheme. As a move to align k6 more closely with the rest of the JS ecosystem, we now allow and encourage users to use full URLs with a scheme (e.g. `import fromurlencoded from "https://jslib.k6.io/form-urlencoded/3.0.0/index.js"`) when they want to load remote files. `file` URLs are also supported as another way to load local modules (normal absolute and relative file paths still work) from the local system, which may be especially useful for Windows scripts.

The old way of importing remote scripts from scheme-less URLs is still supported, though except for the GitHub and cdnjs shortcut loaders, it is in the process of deprecation and will result in a warning.

### Opt-in support for TLS 1.3 and more TLS ciphers (#1084)

Following its opt-in support in Go 1.12, you can now choose to enable support for TLS 1.3 in your k6 scripts. It won't be used by default, but you can enable it by setting the `tlsVersion` (or it's `max` sub-option) to `tls1.3`:

```js
import http from 'k6/http';
import { check } from "k6";

export let options = {
    tlsVersion: {
        min: "tls1.2",
        max: "tls1.3",
    }
};

export default function () {
    let resp = http.get("https://www.howsmyssl.com/a/check");
    check(resp, {
        "status is 200": (resp) => resp.status === 200,
        "tls 1.3": (resp) => resp.json().tls_version === "TLS 1.3",
    });
};
```

Also, all [cipher suites supported by Go](https://golang.org/pkg/crypto/tls/#pkg-constants) 1.12 are now supported by k6 as well. Thanks, @cuonglm!

## Bugs fixed!

* JS: Many fixes for `open()`: (#965)
  - don't panic with an empty filename (`""`)
  - don't make HTTP requests (#963)
  - correctly open simple filenames like `"file.json"` and paths such as `"relative/path/to.txt"` as relative (to the current working directory) paths; previously they had to start with a dot (i.e. `"./relative/path/to.txt"`) for that to happen
  - windows: work with paths starting with `/` or `\` as absolute from the current drive

* HTTP: Correctly always set `response.url` to be the URL that was ultimately fetched (i.e. after any potential redirects), even if there were non http errors. (#990)
* HTTP: Correctly detect connection refused errors on dial. (#998)
* JS: Run imports once per VU. (#975, #1040)
* Config: Fix blacklistIPs JS configuration. Thanks, @THoelzel! (#1004)
* HTTP: Fix a bunch of HTTP measurement and handling issues (#1047)
  - the `http_req_receiving` metric was measured incorrectly (#1041)
  - binary response bodies could get mangled in an `http.batch()` call (#1044)
  - timed out requests could produce wrong metrics (#925)
* JS: Many fixes for importing files and for URL imports in archives. (#1059)
* Config: Stop saving and ignore the derived `execution` values, which were wrongly saved in archive bundles' `metadata.json` by k6 v0.24.0. (#1057, #1076)
* Config: Fix handling of commas in environment variable values specified as CLI flags. (#1077)

## Internals

* CI: removed the gometalinter check in CircleCI, since that project [was deprecated](https://github.com/alecthomas/gometalinter/issues/590) and now exclusively rely on [golangci-lint](https://github.com/golangci/golangci-lint). (#1039)
* Archive bundles: The support for URL imports included a lot of refactoring and internal k6 changes. This included significant changes in the structure of `.tar` archive bundles. k6 v0.25.0 is backwards compatible and can execute bundles generated by older k6 versions, but the reverse is not true. (#1059)
* Archive bundles: The k6 version and the operating system are now saved in the archive bundles' `metadata.json` file. (#1057, #1059)

## Breaking changes

* Previously, the `Content-Length` header value was always automatically set by k6 - if the header value was manually specified by the user, it would have been ignored and silently overwritten. Now, k6 would set the `Content-Length` value only if it wasn't already set by the user. (#989, #1094)
