presign
Open source
presign
SignatureV4.presign()
pre-signs a URL with the AWS Signature V4 algorithm. Given an HTTP request description, it returns a new HTTP request with the AWS signature v4 authorization added. It returns an Object holding a url
containing the authorization information encoded in its query string, ready to use in the context of a k6 HTTP call.
Parameters
The first parameter of the presign
method consists of an Object with the following properties.
Property | Type | Description |
---|---|---|
method | string | The HTTP method of the request |
endpoint | Endpoint | The endpoint of the request. The Endpoint constructor can be imported from both the aws.js bundle, as well as the signature.js file, and takes a string of the form {scheme}://{hostname}[:{port}] as input, allowing to define the target of the request (See provided example below). |
path | string | The path of the request |
headers | Object | The headers of the HTTP request |
You can provide further options and override SignatureV4 options in the context of this specific request.
To do this, pass a second parameter to the presign
method, which is an Object with the following parameters.
Property | Type | Description |
---|---|---|
expiresIn | number | The number of seconds before the pre-signed URL expires |
signingDate | Date | overrides the Date used in the signing operation |
signingService | string | overrides the signer’s AWS service in the context of the sign operation. |
signingRegion | string | overrides the signer’s AWS region in the context of the sign operation |
unsignableHeaders | Set<string> | excludes headers from the signing process |
signableHeaders | Set<string> | mark headers as signed |
Returns
The presign
operation returns an Object with the following properties.
Property | Type | Description |
---|---|---|
headers | Object | The pre-signed request headers to use in the context of a k6 HTTP request |
url | string | The pre-signed url to use in the context of a k6 HTTP request |
Example
JavaScript
import http from 'k6/http';
import { check } from 'k6';
import {
AWSConfig,
Endpoint,
SignatureV4,
AMZ_CONTENT_SHA256_HEADER,
UNSIGNED_PAYLOAD,
} from 'https://jslib.k6.io/aws/0.12.3/signature.js';
const awsConfig = new AWSConfig({
region: __ENV.AWS_REGION,
accessKeyId: __ENV.AWS_ACCESS_KEY_ID,
secretAccessKey: __ENV.AWS_SECRET_ACCESS_KEY,
sessionToken: __ENV.AWS_SESSION_TOKEN,
});
export default function () {
// In order to be able to produce pre-signed URLs,
// we need to instantiate a SignatureV4 object.
const signer = new SignatureV4({
service: 's3',
region: awsConfig.region,
credentials: {
accessKeyId: awsConfig.accessKeyId,
secretAccessKey: awsConfig.secretAccessKey,
sessionToken: awsConfig.sessionToken,
},
/**
* Whether the URI should be escaped or not.
*/
uriEscapePath: false,
/**
* Whether or not the body's hash should be calculated and included
* in the request.
*/
applyChecksum: true,
});
// We can now use the signer to produce a pre-signed URL.
const presignedRequest = signer.presign(
/**
* HTTP request description
*/
{
/**
* The HTTP method we will use in the request.
*/
method: 'GET',
/**
* The endpoint of the service we will be making the request to.
*
* The endpoint is instantiated from a URL string, of the format: `{scheme}://{hostname}[:{port}]`
*/
endpoint: new Endpoint('https://s3.us-east-1.amazonaws.com'),
/**
* The path of the request.
*/
path: '/my-bucket/bonjour.txt',
/**
* The headers we will be sending in the request.
*
* Note that in the specific case of this example, requesting
* an object from S3, we want to set the `x-amz-content-sha256`
* header to `UNSIGNED_PAYLOAD`. That way, we bypass the payload
* hash calculation, and communicate that value instead, as specified.
*/
headers: { [AMZ_CONTENT_SHA256_HEADER]: 'UNSIGNED-PAYLOAD' },
},
/**
* (optional) pre-sign operation options.
*/
{
/**
* The number of seconds before the pre-signed URL expires
*/
expiresIn: 86400,
/**
* A set of strings whose representing headers that should not be hoisted
* to pre-signed request's query string. If not supplied, the pre-signer
* moves all the AWS-specific headers (starting with `x-amz-`) to the request
* query string. If supplied, these headers remain in the pre-signed request's
* header.
* All headers in the provided request will have their names converted to
* lower case and then checked for existence in the unhoistableHeaders set.
*
* In the case of pre-signing S3 URLs, the body needs to be empty.
* however, the AMZ_CONTENT_SHA256_HEADER needs to be set to
* UNSIGNED_PAYLOAD. To do this, we need to set the header,
* but declare it as unhoistable, and unsignable.
*/
unhoistableHeaders: new Set([AMZ_CONTENT_SHA256_HEADER]),
/**
* A set of strings whose members represents headers that cannot be signed.
* All headers in the provided request will have their names converted to
* lower case and then checked for existence in the unsignableHeaders set.
*
* In the case of pre-signing S3 URLs, the body needs to be empty.
* however, the AMZ_CONTENT_SHA256_HEADER needs to be set to
* UNSIGNED_PAYLOAD. To do this, we need to set the header,
* but declare it as unhoistable, and unsignable.
*/
unsignableHeaders: new Set([AMZ_CONTENT_SHA256_HEADER]),
/**
* A set of strings whose members represents headers that should be signed.
* Any values passed here will override those provided via unsignableHeaders,
* allowing them to be signed.
*
* All headers in the provided request will have their names converted to
* lower case before signing.
*/
signableHeaders: new Set(),
/**
* The date and time to be used as signature metadata. This value should be
* a Date object, a unix (epoch) timestamp, or a string that can be
* understood by the JavaScript `Date` constructor.If not supplied, the
* value returned by `new Date()` will be used.
*/
signingDate: new Date(),
/**
* The service signing name. It will override the service name of the signer
* in current invocation
*/
signingService: 's3',
/**
* The signingRegion and signingService options let the user
* specify a different region or service to pre-sign the request for.
*/
signingRegion: 'us-east-1',
}
);
console.log(`presigned URL: ${presignedRequest.url}`);
/**
* Our URL is now ready to be used.
*/
const res = http.get(presignedRequest.url, {
headers: presignedRequest.headers,
});
check(res, { 'status is 200': (r) => r.status === 200 });
}
Was this page helpful?
Related documentation
Related resources from Grafana Labs
Additional helpful documentation, links, and articles:
60 min

Performance testing and observability in Grafana Cloud
In this webinar, learn how Grafana Cloud k6 offers you the best developer experience for performance testing.
60 min

User-centered observability: load testing, real user monitoring, and synthetics
Learn how to use load testing, synthetic monitoring, and real user monitoring (RUM) to understand end users' experience of your apps. Watch on demand.