Skip to content

Instantly share code, notes, and snippets.

Keybase proof

I hereby claim:

  • I am anandkunal on github.
  • I am impvka (https://keybase.io/impvka) on keybase.
  • I have a public key ASBjDikMvXd4VPuD27Sj-ADxx-ERd1LLCOe-MMs5OHU2ZQo

To claim this, I am signing this object:

@anandkunal
anandkunal / README.md
Last active February 10, 2023 09:52
AWS SigV4 & SES Walkthrough in Go

AWS SigV4 & SES Walkthrough in Go

A few years ago, I helped a non-profit organization build and deploy a series of web applications and micro-services on top of AWS. One of the services was responsible for sending out email notifications to people via AWS SES.

Back then, I wrote a really simple program in Go that made direct calls to the AWS API. Instead of using an official library, I read the API specification, learned how to authenticate requests, and implemented a fairly trivial SDK. The code was succinct, readable, and worked perfectly for 3 years without any issues.

That is until this past week…

AWS recently updated the specification, we’re now at Signature Version 4 (SigV4), for how API requests must be formed and signed by clients. In this walkthrough, I’ll share the full Go source code (~130 LOC) that I put together to make valid authenticated calls to AWS for SES. You don’t need to be knowledgeable about Go to grok code in this post. In fact, code in this post will translate pretty cleanly to

@anandkunal
anandkunal / simple_reverse_proxy.go
Created September 4, 2012 21:12
Simple reverse proxy in Go.
package main
import (
"log"
"net/http"
"net/http/httputil"
"net/url"
)
func main() {
class Thing(object):
def __init__(self):
self.__missing_method_name = None # Hack!
def __getattribute__(self, name):
return object.__getattribute__(self, name)
def __getattr__(self, name):
self.__missing_method_name = name # Could also be a property
return getattr(self, '__methodmissing__')
<?php
// Fired for 404 errors
ToroHook::add("404", function() {});
// Before/After callbacks in order
ToroHook::add("before_request", function() {});
ToroHook::add("before_handler", function() {});
ToroHook::add("after_handler", function() {});
ToroHook::add("after_request", function() {});
<?php
class ExampleHandler {
function get() {}
function post() {}
function get_xhr() {}
function post_xhr() {}
}
<?php
Toro::serve(array(
"/" => "SplashHandler",
"/catalog/page/:number" => "CatalogHandler",
"/product/:alpha" => "ProductHandler",
"/manufacturer/:string" => "ManufacturerHandler"
));
<?
include("toro.php");
// Domain object, not included, just for following along
include("domain/user.php");
class V1UserCreateHandler extends ToroHandler {
private function fail($error_type="") {
echo json_encode(array("success" => false, "error_type" => $error_type));
exit;
RewriteEngine on
RewriteCond $1 !^(index\.php)
RewriteRule ^(.*)$ index.php/$1 [L]
// Invert the color spectrum
Surface::Iter iter(newSurface.getIter());
while(iter.line()) {
while(iter.pixel()) {
iter.r() = 255 - iter.r();
iter.g() = 255 - iter.g();
iter.b() = 255 - iter.b();
}
}