Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

maginepro/http4s-aws

Open more actions menu

Repository files navigation

🔒 http4s-aws

Provides http4s request authentication using AWS Signature Version 4 signing.
The blog post A Scala Alternative to AWS SDK for Java gives an introduction.
Inspired by filosganga/http4s-aws, but with significant differences.

Usage

You can add the following lines to build.sbt to use the library.

libraryDependencies ++= Seq(
  "com.magine" %% "http4s-aws" % http4sAwsVersion,
  "com.magine" %% "http4s-aws-s3" % http4sAwsVersion
)

Make sure to replace http4sAwsVersion with a release version.
Replace %% with %%% if you are using Scala.js or Scala Native.

Signing

Create a CredentialsProvider and use AwsSigningClient to wrap an existing client.

import cats.effect.IO
import cats.effect.IOApp
import com.magine.aws.Region
import com.magine.http4s.aws.AwsServiceName
import com.magine.http4s.aws.AwsSigningClient
import com.magine.http4s.aws.CredentialsProvider
import org.http4s.ember.client.EmberClientBuilder
import org.http4s.Request

object Main extends IOApp.Simple {
  def run: IO[Unit] = {
    val client =
      for {
        client <- EmberClientBuilder.default[IO].build
        provider <- CredentialsProvider.default(client)
        region = Region.EU_WEST_1
        serviceName = AwsServiceName.Elasticsearch
        signingClient = AwsSigningClient(provider, region, serviceName)(client)
      } yield signingClient

    val request: Request[IO] =
      Request()

    client.use(_.expect[Unit](request))
  }
}

Chunking

For chunked uploads, set Transfer-Encoding: chunked and set the X-Amz-Decoded-Content-Length header to the total length of the request body. In this case, avoid setting the Content-Length header, since it will then also have to account for the signing content length.

Pre-signing

If pre-signing of requests is necessary, use AwsPresigning.

import cats.effect.IO
import cats.effect.IOApp
import com.magine.aws.Region
import com.magine.http4s.aws.AwsPresigning
import com.magine.http4s.aws.AwsServiceName
import com.magine.http4s.aws.CredentialsProvider
import org.http4s.ember.client.EmberClientBuilder
import org.http4s.Request
import scala.concurrent.duration._

object Main extends IOApp.Simple {
  def run: IO[Unit] = {
    val presigning =
      for {
        client <- EmberClientBuilder.default[IO].build
        provider <- CredentialsProvider.default(client)
        region = Region.EU_WEST_1
        serviceName = AwsServiceName.S3
        expiry = 5.minutes
        presigning = AwsPresigning(provider, region, serviceName, expiry)
      } yield presigning

    val request: Request[IO] =
      Request()

    presigning
      .use(_.presign(request))
      .map(_.uri.renderString)
      .flatMap(IO.println)
  }
}

S3

The http4s-aws-s3 module adds support for Amazon S3 multipart uploads.

import cats.effect.IO
import cats.effect.IOApp
import com.magine.aws.Region
import com.magine.http4s.aws.CredentialsProvider
import com.magine.http4s.aws.s3.S3MultipartUpload
import com.magine.http4s.aws.s3.syntax.*
import fs2.Stream
import fs2.text
import io.circe.Json
import org.http4s.MediaType
import org.http4s.ember.client.EmberClientBuilder
import org.http4s.headers.`Content-Type`

object Main extends IOApp.Simple {
  def run: IO[Unit] = {
    val multipartUpload =
      for {
        client <- EmberClientBuilder.default[IO].build
        provider <- CredentialsProvider.default(client)
        bucket = bucket"bucket"
        key = key"key"
        region = Region.EU_WEST_1
        multipartUpload = S3MultipartUpload(client, provider, region)
          .withContentType(`Content-Type`(MediaType.application.json))
          .withMaxConcurrentUploads(5)
          .uploadTo(bucket, key)
      } yield multipartUpload

    multipartUpload.use { multipartUpload =>
      Stream(Json.obj())
        .map(_.noSpaces)
        .through(text.utf8.encode)
        .through(multipartUpload)
        .compile
        .onlyOrError
        .flatMap(IO.println)
    }
  }
}

About

Signed AWS API requests for http4s 🔒

Topics

Resources

License

Stars

Watchers

Forks

Contributors

Languages

Morty Proxy This is a proxified and sanitized view of the page, visit original site.