Class, constructor and inherance.

holo via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Oct 15 20:14:02 PDT 2015


I created interface IfRequestHandler it is used only by one class 
RequestHandlerXML right now but thanks to such solution i can 
create more classes with same interface which can handle it in 
different way.. eg second can be RequestHandlerCSVReport or 
RequestHandlerSendViaEmail. Is it this what you ware mentioning? 
Bellow working code:

/////////
//main.d:
/////////

#!/usr/bin/rdmd

import std.stdio, sigv4, conf;



void main()
{
     ResultHandlerXML hand = new ResultHandlerXML;
     SigV4 req = new SigV4(hand);

     //req.ResultHandler = hand;
     req.go();
     hand.processResult();

}

/////////
//conf.d:
/////////

module conf;

import std.stdio, std.process;
import std.net.curl:exit;

interface IfConfig
{
     void set(string val, string var);
     string get(string var);
}


class Config : IfConfig
{
     this()
     {
         this.accKey = environment.get("AWS_ACCESS_KEY");
         if(accKey is null)
         {
             writeln("accessKey not available");
             exit(-1);
         }
         this.secKey = environment.get("AWS_SECRET_KEY");
         if(secKey is null)
         {
             writeln("secretKey not available");
             exit(-1);
         }
     }

     public:

         void set(string val, string var)
         {
             switch(var)
             {
                 case "accKey": accKey = val; break;
                 case "secKey": secKey = val; break;
                 default: writeln("Can not be set, not such 
value");
             }
         }


         string get(string var)
         {
             string str = "";

             switch(var)
             {
             case "accKey": return accKey;
             case "secKey": return secKey;
             default: writeln("Can not be get, not such value");
             }

             return str;
         }


  //   private:

         string accKey;
         string secKey;

}

/////////
//sigv4.d
/////////

module sigv4;

import std.stdio, std.process;
import std.digest.sha, std.digest.hmac;
import std.string;
import std.conv;
import std.datetime;
import std.net.curl;
import conf;


interface IfSigV4
{
	IfResultHandler go(ResultHandlerXML ResultHandler);
}

interface IfResultHandler
{
         void setResult(int content);
         void processResult();
}

class ResultHandlerXML : IfResultHandler
{
     void setResult(int content)
     {
         this.xmlresult = content;
     }

     void processResult()
     {
         writeln(xmlresult);
     }

     private:
         int xmlresult;
}

class SigV4 : IfSigV4
{
	//could be changed to take some structure as parameter instead 
of such ammount of attributes

	this(string methodStr = "GET", string serviceStr = "ec2", string 
hostStr = "ec2.amazonaws.com", string regionStr = "us-east-1", 
string endpointStr = "https://ec2.amazonaws.com", string 
payloadStr = "", string parmStr = "Action=DescribeInstances")
	in
	{
		writeln(parmStr);
	}
	body
	{
         conf.Config config = new conf.Config;

		this.method = methodStr;
		this.service = serviceStr;
		this.host = hostStr;
		this.region = regionStr;
		this.endpoint = endpointStr;
		this.payload = payloadStr;
		this.requestParameters = parmStr;

		this.accessKey = config.get("accKey");
		if(accessKey is null)
		{
			writeln("accessKey not available");
			exit(-1);
		}
		this.secretKey = config.get("secKey");
		if(secretKey is null)
                 {
                         writeln("secretKey not available");
			exit(-1);
                 }

	}

	public:
		string method;
		string service;
		string host;
		string region;
		string endpoint;
		string payload;
		string requestParameters;

		IfResultHandler ResultHandler;




		IfResultHandler go(ResultHandlerXML ResultHandler)
		{
			//time need to be set when we are sending request not before
			auto currentClock = Clock.currTime(UTC());
			auto currentDate = cast(Date)currentClock;
			auto curDateStr = currentDate.toISOString;
			auto currentTime = cast(TimeOfDay)currentClock;
			auto curTimeStr = currentTime.toISOString;
			auto xamztime = curDateStr ~ "T" ~ curTimeStr ~ "Z";

			canonicalURI = "/";
			canonicalQueryString = requestParameters ~ this.Version;
			canonicalHeadersString =  "host:" ~ this.host ~ "\n" ~ 
"x-amz-date:" ~ xamztime ~ "\n";
			signedHeaders = "host;x-amz-date";

			auto canonicalRequest = getCanonicalRequest(canonicalURI, 
canonicalQueryString, canonicalHeadersString, signedHeaders);

			string credentialScope = curDateStr ~ "/" ~ region ~ "/" ~ 
service ~ "/" ~ "aws4_request";

			string stringToSign = algorithm ~ "\n" ~ xamztime ~ "\n" ~ 
credentialScope ~ "\n" ~ 
sha256Of(canonicalRequest).toHexString.toLower;

			auto signingKey = getSignatureKey(secretKey, curDateStr, 
region, service);

			string signature = hmac!SHA256(stringToSign.representation, 
signingKey).toHexString.toLower;

			string authorizationHeader = algorithm ~ " " ~ "Credential=" ~ 
accessKey ~ "/" ~ credentialScope ~ ", " ~ "SignedHeaders=" ~ 
signedHeaders ~ ", " ~ "Signature=" ~ signature;

			auto client = HTTP(endpoint ~ "?" ~ canonicalQueryString);
			client.method = HTTP.Method.get;
			client.addRequestHeader("x-amz-date", xamztime);
			client.addRequestHeader("Authorization", authorizationHeader);
			auto content = client.perform();

             writeln(content);

			ResultHandler.setResult(content);
                         return ResultHandler;
		}

	private:
		const string algorithm = "AWS4-HMAC-SHA256";
		const string Version = "&Version=2013-10-15";

		string accessKey;
		string secretKey;



		string canonicalURI;
		string canonicalQueryString;
	       	string canonicalHeadersString;
	       	string signedHeaders;



		alias sign = hmac!SHA256;

		auto getSignatureKey(string key, string dateStamp, string 
regionName, string serviceName)
		{
			auto kString = ("AWS4" ~ key).representation;
			auto kDate = sign(dateStamp.representation, kString);
			auto kRegion = sign(regionName.representation, kDate);
			auto kService = sign(serviceName.representation, kRegion);
			auto kSigning = sign("aws4_request".representation, kService);

			return kSigning;
		}


		auto getCanonicalRequest(string canonicalURI, string 
canonicalQueryString, string canonicalHeadersString, string 
signedHeaders)
		{
			string payloadHash = sha256Of(payload).toHexString.toLower;
			string canonicalRequest = method ~ "\n" ~ canonicalURI ~ "\n" 
~ canonicalQueryString ~ "\n" ~ canonicalHeadersString ~ "\n" ~ 
signedHeaders ~ "\n" ~ payloadHash;
			return canonicalRequest;
		}
}




More information about the Digitalmars-d-learn mailing list