Skip to content

Instantly share code, notes, and snippets.

@Saeven

Saeven/gist:7832090

Last active Mar 31, 2020
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"
}');
@HairyDuck

This comment has been minimized.

Copy link

@HairyDuck HairyDuck 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

@sbtsrbayer sbtsrbayer 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

@prasanthnarasimha prasanthnarasimha 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