Last active
October 21, 2021 15:44
-
-
Save amancevice/6b55057920ee1b0b5d36be985b3365fc to your computer and use it in GitHub Desktop.
Send signed HTTP requests to AWS with Ruby
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'net/http' | |
require 'aws-sdk-core' | |
## | |
# Example usage: | |
# uri = URI 'https://events.ksr.io/fizz/buzz' | |
# req = Net::HTTP::Post.new(uri, 'content-type' => 'application/json') | |
# Aws::HTTP.start(uri.host, uri.port, use_ssl: true) do |http| | |
# http.request(req, { fizz: 'buzz' }.to_json) | |
# end | |
class Aws::HTTP < Net::HTTP | |
class << self | |
## | |
# Sign an instance of Net::HTTPRequest (Net::HTTP::Post, etc) | |
def sign(req, body = nil) | |
# Get signing params | |
signing_params = { | |
http_method: req.method, | |
url: req.uri.to_s, | |
headers: req.each_header.to_h, | |
body: body || req.body, | |
} | |
# Generate signature | |
signature = signer.sign_request(**signing_params) | |
# Update headers from signature | |
req['authorization'] = signature.headers['authorization'] | |
req['host'] = signature.headers['host'] | |
req['x-amz-content-sha256'] = signature.headers['x-amz-content-sha256'] | |
req['x-amz-date'] = signature.headers['x-amz-date'] | |
req['x-amz-security-token'] = signature.headers['x-amz-security-token'] | |
# Return request | |
req | |
end | |
## | |
# Get Aws::Sigv4::Signer | |
# Use default Aws::STS::Client as proxy for getting credentials & region | |
def signer | |
@signer ||= begin | |
client = Aws::STS::Client.new | |
Aws::Sigv4::Signer.new( | |
credentials: client.config.credentials.credentials, | |
region: client.config.region, | |
service: 'execute-api', | |
) | |
end | |
end | |
## | |
# Set signer in case a more advanced usage is needed | |
def signer=(signer) | |
@signer = signer | |
end | |
end | |
## | |
# Sign request | |
def sign(req, body = nil) | |
Aws::HTTP.sign(req, body) | |
end | |
## | |
# Sign request before transport | |
def request(req, body = nil, &block) | |
sign(req, body) | |
super | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment