Sometimes you don’t have access to the S3 console, but you do have keys for a bucket. If you need to change CORS for that bucket, it turns out you can. Boto has API methods for this.
# -*- coding: utf-8 -*-
from boto.s3.connection import S3Connection
from boto.s3.bucket import Bucket
AWS_ACCESS_KEY = 'YOUR KEY HERE'
AWS_SECRET_KEY = 'YOUR KEY HERE'
S3_BUCKET = 'YOUR BUCKET HERE'
cors_xml = """
*
GET
POST
*
"""
connection = S3Connection(AWS_ACCESS_KEY, AWS_SECRET_KEY)
bucket = Bucket(connection, S3_BUCKET)
print "Current CORS:"
print bucket.get_cors_xml()
bucket.set_cors_xml(cors_xml)
print "New CORS:"
print bucket.get_cors_xml()
A Problem
“@jmhobbs thanks for your amazonses swiftmailer integration. it works. can’t understand your code tho. way over my head.”
– @rrcatto
“@rrcatto no problem! Neither can I sometimes. :-)”
– @jmhobbs
After this exchange, I thought I would dig back into this project and outline how it works.
Three Core Classes
There are really only two classes in play with this project. The first is Swift_AWSInputByteStream, the second is the transport itself, Swift_AWSTransport. The third, and possibly the most confusing, is ChunkedTransferSocket.
So let’s got over each of them.
Swift_AWSInputByteStream
The purpose of this class is to write out the contents of the message to the provided socket. We have this special class for AWS because the documentation specifies that the message data should be Base64 encoded. One side effect of Base64 is padding on encoding. Because of this, we buffer any excess bytes and encode only on multiples of 3 bytes received.
Here is a documented version of the core function, write:
public function write($bytes) {
// Get the buffer size + new chunk size
$total_size = strlen( $this->buffer ) + strlen( $bytes );
// Size of the remainder we will need to buffer
$excess = $total_size % 3;
// Nothing to write? Return early.
if( $total_size - $excess == 0 ) { return ++$this->counter; }
// Encode and write bytes to the socket
$this->socket->write(
urlencode(
base64_encode(
substr(
$this->buffer . $bytes, // Source is buffer + new chunk
0, // Begin at the beginning
$total_size - $excess // Write up to the new buffer
)
)
)
);
// If there was excess, store it in the buffer
if( $excess != 0 ) {
$this->buffer = substr( $this->buffer . $bytes, -1 * $excess );
}
else {
$this->buffer = '';
}
return ++$this->counter;
}
Swift_AWSTransport
This class provides the transport for Swiftmailer. It sets up the socket, takes a message, and sends it off to AWS. The core functionality is in _doSend. This function is documented below. I’m not detailing much here, because it’s mostly glue code.
protected function _doSend(
Swift_Mime_Message $message,
&$failedRecipients = null
) {
// Use secret key to generate HMAC used to
// authorize the message to AWS
$date = date( 'D, j F Y H:i:s O' );
// Use the native extension if available
if(
function_exists( 'hash_hmac' ) and
in_array( 'sha1', hash_algos() )
) {
$hmac = base64_encode(
hash_hmac( 'sha1', $date, $this->AWSSecretKey, true )
);
}
// Otherwise, fallback to a PHP implementation
else {
$hmac = $this->calculate_RFC2104HMAC( $date, $this->AWSSecretKey );
}
// Now we use that to create the authorization header
$auth = "AWS3-HTTPS AWSAccessKeyId=" .
$this->AWSAccessKeyId .
", Algorithm=HmacSHA1, Signature=" .
$hmac;
$host = parse_url( $this->endpoint, PHP_URL_HOST );
$path = parse_url( $this->endpoint, PHP_URL_PATH );
// Open up a raw SSL socket to the host
$fp = fsockopen( 'ssl://' . $host , 443, $errno, $errstr, 30 );
if( ! $fp ) {
throw new AWSConnectionError( "$errstr ($errno)" );
}
// Convert that into a chunked "socket"
$socket = new ChunkedTransferSocket( $fp, $host, $path );
// Add our date and auth headers (generated above)
$socket->header("Date", $date);
$socket->header("X-Amzn-Authorization", $auth);
// Write the initial post parameters
$socket->write("Action=SendRawEmail&RawMessage.Data=");
// Hand it off to an Swift_AWSInputByteStream to write the message
$ais = new Swift_AWSInputByteStream($socket);
$message->toByteStream($ais);
$ais->flushBuffers();
$result = $socket->read();
return $result;
}
Okay, not simple, but fairly straightforward.
ChunkedTransferSocket
This class makes an HTTP request direct on the socket. Since we don’t know the message size before encoding, and it’s memory intensive to encode, buffer, and then send, we do a chunked transfer encoding POST.
It’s actually pretty easy. You send some headers, and then every time you have a chunk to write, you preface it with the number of bytes you are sending before you send them.
Here’s the code for the write function:
public function write ( $chunk ) {
if( $this->write_finished ) { throw new InvalidOperationException( "Can not write, reading has started." ); }
if( ! $this->write_started ) {
fwrite( $this->socket, "\r\n" ); // Start message body
$this->write_started = true;
}
// Write the length of the chunk, carriage return and new line
fwrite( $this->socket, sprintf( "%x\r\n", strlen( $chunk ) ) );
// Write the chunk
fwrite( $this->socket, $chunk . "\r\n" );
// Flush the socket to send the data now, not later
fflush( $this->socket );
}
Pretty simple once you understand how chunked transfer works. The rest of the class is just state keeping.
Conclusion
So, that’s that. Nothing really deep in there, just a collection of fairly simple methods that, glued together, send email to AWS SES.
Hit me up with any questions in the comments section if you have them.
So I wanted a VPN this weekend for working from coffee shops and the like. I found a good recipe for a PPTP install and set it up on an EC2 Micro, physician which happens to fall in the free tier. Free VPN!
During the process I went ahead and turned it into a script. It only takes a few seconds to run and will set you up for good.
Ther are side effects to this script. If you have made any changes to /etc/rc.local they will get removed, discount sorry. On a fresh install it will be fine.
You can read though it here: https://gist.github.com/950539 and after logging into your instance, you can use it like so:
$ wget https://gist.github.com/raw/950539/pptpd.sh
$ sudo su
# /bin/bash pptpd.sh
Bonus!
To connect to this VPN from KDE4, I had to do a little config song and dance. Screenshot follows:

KDE4 NM VPN Advanced Settings
So, today Amazon debuted Simple Email Service. The gist of it is, send mail with them instead of your own servers. Like a feature reduced SendGrid or Postmark.
Not a lot of stuff out there for it so I thought I’d jump the gun a bit and write a transport for PHP’s Swiftmailer. If you have to send e-mail from your sever and from PHP, Swiftmailer is your best friend.
Never dug into Swiftmailer’s guts before, but it’s pretty well laid out. All you have to do for a new transport is implement the send method of the Transport interface and you are done.
I knocked mine together pretty quick, and the only code I cribbed was the HMAC code from php-aws, because AWS was rejecting the output from hash_hmac. (Which I literally just figured out while I wrote that paragraph. Works now.)
So how hard is it to use? Easy as any other transport in Swiftmailer.
setSubject("What up?")
->setFrom(array('[email protected]'))
->setTo(array('[email protected]'))
->setBody("
Dude, I'm totally sending you email via AWS.
", 'text/html');
$mailer->send( $message );

So, yeah, it works.
I know there is a ton of stuff I didn’t implement that I need to before this could be “production” ready, but it was a very satisfying little project.
You can grab it here: https://github.com/jmhobbs/Swiftmailer-Transport–AWS-SES