Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
RAW Curl Post to AWS Kinesis with PHP
<?php
/*
POST / HTTP/1.1
Host: kinesis.<region>.<domain>
x-amz-Date: <Date>
Authorization: AWS4-HMAC-SHA256 Credential=<Credential>, SignedHeaders=content-type;date;host;user-agent;x-amz-date;x-amz-target;x-amzn-requestid, Signature=<Signature>
User-Agent: <UserAgentString>
Content-Type: application/x-amz-json-1.1
Content-Length: <PayloadSizeBytes>
Connection: Keep-Alive
X-Amz-Target: Kinesis_20130901.PutRecord
{
"StreamName": "exampleStreamName",
"Data": "XzxkYXRhPl8x",
"PartitionKey": "partitionKey"
}
*/
/**
*
*/
class AWSK
{
static $utc_tz;
const ACCESS_KEY = '';
const SECRET_KEY = '';
function kinesis( $payload )
{
if( !self::$utc_tz )
self::$utc_tz = new \DateTimeZone( 'UTC' );
$APIVERSION = '20131104';
$datestamp = new \DateTime( "now", self::$utc_tz );
$longdate = $datestamp->format( "Ymd\\THis\\Z");
$shortdate = $datestamp->format( "Ymd" );
// establish the signing key
{
$ksecret = 'AWS4' . self::SECRET_KEY;
$kdate = hash_hmac( 'sha256', $shortdate, $ksecret, true );
$kregion = hash_hmac( 'sha256', 'us-east-1', $kdate, true );
$kservice = hash_hmac( 'sha256', 'kinesis', $kregion, true );
$ksigning = hash_hmac( 'sha256', 'aws4_request', $kservice, true );
}
// command parameters
$params = array(
'host' => 'kinesis.us-east-1.amazonaws.com',
'content-type' => 'application/x-amz-json-1.1',
'x-amz-date' => $longdate,
'x-amz-target' => 'Kinesis_'. $APIVERSION . '.PutRecord',
'content-length' => strlen( $payload ),
'user-agent' => 'LDP',
'connection' => 'keep-alive',
);
$canonical_request = $this->createCanonicalRequest( $params, $payload );
$signed_request = hash( 'sha256', $canonical_request );
$sign_string = "AWS4-HMAC-SHA256\n{$longdate}\n$shortdate/us-east-1/kinesis/aws4_request\n" . $signed_request;
$signature = hash_hmac( 'sha256', $sign_string, $ksigning );
$params['authorization'] = "AWS4-HMAC-SHA256 Credential=" . self::ACCESS_KEY . "/$shortdate/us-east-1/kinesis/aws4_request, " .
"SignedHeaders=" . implode( ";", array_keys( $params ) ) . ", " .
"Signature=$signature";
/*
* Execute Crafted Request
*/
$url = "https://kinesis.us-east-1.amazonaws.com";
$ch = curl_init();
$curl_headers = array();
foreach( $params as $p => $k )
$curl_headers[] = $p . ": " . $k;
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_POST,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_HTTPHEADER, $curl_headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_TCP_NODELAY, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false );
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false );
// debug opts
{
curl_setopt($ch, CURLOPT_VERBOSE, true);
$verbose = fopen('php://temp', 'rw+');
curl_setopt($ch, CURLOPT_STDERR, $verbose);
$result = curl_exec($ch); // raw result
rewind($verbose);
$verboseLog = stream_get_contents($verbose);
echo "Verbose information:\n<pre>", htmlspecialchars($verboseLog), "</pre>\n";
}
var_dump( $result );
}
private function createCanonicalRequest( Array $params, $payload )
{
$canonical_request = array();
$canonical_request[] = 'POST';
$canonical_request[] = '/';
$canonical_request[] = '';
$can_headers = array(
'host' => 'kinesis.us-east-1.amazonaws.com'
);
foreach( $params as $k => $v )
$can_headers[ strtolower( $k ) ] = trim( $v );
uksort( $can_headers, 'strcmp' );
foreach ( $can_headers as $k => $v )
$canonical_request[] = $k . ':' . $v;
$canonical_request[] = '';
$canonical_request[] = implode( ';', array_keys( $can_headers ) );
$canonical_request[] = hash( 'sha256', $payload );
$canonical_request = implode( "\n", $canonical_request );
return $canonical_request;
}
}
$a = new AWSK();
$a->kinesis( '{
"StreamName": "promotion-tracking",
"Data": "XzxkYXRhPl8x",
"PartitionKey": "test"
}');
@luke908

This comment has been minimized.

Copy link

commented Jun 12, 2014

I've adapted this for DyanamoDB but I'm recieveing the following error:
"The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details."

What can I do to fix this?

@sbtsrbayer

This comment has been minimized.

Copy link

commented Mar 10, 2017

Thank you very much for this code. I fought the AWS sdk and Guzzle to no avail, but this worked liked a charm still.

@prasanthnarasimha

This comment has been minimized.

Copy link

commented Sep 11, 2017

Thank you so much.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.