Class, constructor and inherance.

Rikki Cattermole via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Oct 15 21:04:11 PDT 2015


On 16/10/15 4:14 PM, holo wrote:
> 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;
>          }
> }

I was thinking along the lines of a new object per result.
But that sorta also works, since the handler can be and will be reused.



More information about the Digitalmars-d-learn mailing list