diff --git a/src/content/docs/r2/examples/aws/aws-sdk-kotlin.mdx b/src/content/docs/r2/examples/aws/aws-sdk-kotlin.mdx new file mode 100644 index 000000000000000..2041f9be0ced6d4 --- /dev/null +++ b/src/content/docs/r2/examples/aws/aws-sdk-kotlin.mdx @@ -0,0 +1,126 @@ +--- +title: aws-sdk-kotlin +pcx_content_type: example +--- + +import { Render } from "~/components"; + + +
+ +This example uses the [aws-sdk-kotlin](https://github.com/aws/aws-sdk-kotlin). You must pass in the R2 configuration credentials when instantiating your `S3` client: + +## Basic Usage + +```kotlin +import aws.sdk.kotlin.runtime.auth.credentials.StaticCredentialsProvider +import aws.sdk.kotlin.services.s3.S3Client +import aws.sdk.kotlin.services.s3.model.ListObjectsV2Request +import aws.smithy.kotlin.runtime.auth.awscredentials.Credentials +import aws.smithy.kotlin.runtime.net.url.Url +import kotlinx.coroutines.runBlocking + +val ACCOUNT_ID = "" +val ACCESS_KEY_ID = "" +val SECRET_ACCESS_KEY = "" + +fun main() = runBlocking { + S3Client.fromEnvironment { + region = "auto" // Required by SDK, but not used by R2 + endpointUrl = Url.parse("https://${ACCOUNT_ID}.r2.cloudflarestorage.com") + credentialsProvider = StaticCredentialsProvider( + Credentials( + accessKeyId = ACCESS_KEY_ID, + secretAccessKey = SECRET_ACCESS_KEY + ), + ) + }.use { r2Client -> + println("Available buckets:") + r2Client.listBuckets().buckets?.forEach { bucket -> + println("* ${bucket.name}") + } + + val bucketName = "" + println("\nObjects in bucket '${bucketName}':") + r2Client.listObjectsV2(ListObjectsV2Request { bucket = bucketName }).contents?.forEach { + println("* ${it.key} (size: ${it.size} bytes, modified: ${it.lastModified})") + } + } +} +``` + +```sh output +Available buckets: +* my-bucket-1 +* my-bucket-2 + +Objects in bucket 'my-bucket-1': +* image1.png (size: 253167 bytes, modified: 2026-01-17T11:30:58.896Z) +* image2.png (size: 247027 bytes, modified: 2026-01-17T11:30:57.779Z) +``` + +## Generate presigned URLs + +You can also generate presigned links that can be used to temporarily share public read or write access to a bucket. + +```kotlin +import aws.sdk.kotlin.runtime.auth.credentials.StaticCredentialsProvider +import aws.sdk.kotlin.services.s3.S3Client +import aws.sdk.kotlin.services.s3.model.GetObjectRequest +import aws.sdk.kotlin.services.s3.model.PutObjectRequest +import aws.sdk.kotlin.services.s3.presigners.presignGetObject +import aws.sdk.kotlin.services.s3.presigners.presignPutObject +import aws.smithy.kotlin.runtime.auth.awscredentials.Credentials +import aws.smithy.kotlin.runtime.net.url.Url +import kotlinx.coroutines.runBlocking +import kotlin.time.Duration.Companion.minutes + +val ACCOUNT_ID = "" +val ACCESS_KEY_ID = "" +val SECRET_ACCESS_KEY = "" + +fun main() = runBlocking { + S3Client.fromEnvironment { + region = "auto" // Required by SDK, but not used by R2 + endpointUrl = Url.parse("https://${ACCOUNT_ID}.r2.cloudflarestorage.com") + credentialsProvider = StaticCredentialsProvider( + Credentials( + accessKeyId = ACCESS_KEY_ID, + secretAccessKey = SECRET_ACCESS_KEY + ), + ) + }.use { r2Client -> + val bucketName = "" + + val uploadUrl = r2Client.presignPutObject( + input = PutObjectRequest { + bucket = bucketName + key = "README.md" + }, + duration = 15.minutes, + ).url + println(uploadUrl) + + val getUrl = r2Client.presignGetObject( + input = GetObjectRequest { + bucket = bucketName + key = "README.md" + }, + duration = 15.minutes, + ).url + println(getUrl) + } +} +``` + +You can use these presigned URLs with any HTTP client. For example, to upload a file using the PUT URL: + +```bash +curl -X PUT "https://" -H "Content-Type: application/octet-stream" --data-binary "@local-file.txt" +``` + +To download a file using the GET URL: + +```bash +curl -X GET "https://" -o downloaded-file.txt +```