Rv1
Rv1

Reputation: 185

Uploading new images to Azure FileService using 'CREATEFILE' service

I'm trying to upload the images to FILE SERVICE in Azure using REST API(CREATE FILE) documentation specified here: https://learn.microsoft.com/en-us/rest/api/storageservices/create-file

Here is my code, which is not working:

public class azure_cls_cpy {
    public string fileName {get; set;}
    public integer fileSize {get; set;}
    public blob img {get; set;}

    public void createImage(){
        string storageKey = 'account-key';
        string storageName = 'account-name';
        string shareName = 'share-name';
        Datetime dt = Datetime.now();
        string formattedDate = dt.formatGMT('EEE, dd MMM yyyy HH:mm:ss')+ ' GMT';
        system.debug('formattedDate--'+formattedDate);
        system.debug('fileSize--'+fileSize);
        integer imageSize = img.size();
        system.debug('imageSize--'+imageSize);
        string CanonicalizedHeaders = 'x-ms-content-length:'+string.valueOf(fileSize)+'\nx-ms-date:'+formattedDate+'\nx-ms-type:file\nx-ms-version:2016-05-31';

        string CanonicalizedResource = '/' + storageName + '/' + shareName + '/' +fileName;
        string StringToSign = 'PUT\n\n\n\n\nimage/png\n\n\n\n\n\n\n' + CanonicalizedHeaders+'\n'+CanonicalizedResource;
        system.debug('StringToSign--'+StringToSign);

        Blob temp = EncodingUtil.base64Decode(storageKey);
        Blob hmac = Crypto.generateMac('HmacSHA256',Blob.valueOf(StringToSign),temp ); 
        HttpRequest req = new HttpRequest();
        req.setMethod('PUT');
        req.setHeader('x-ms-version','2016-05-31' );
        req.setHeader('x-ms-date', formattedDate);
        req.setHeader('x-ms-content-length',string.valueOf(fileSize));
        req.setHeader('x-ms-type','file');
        req.setHeader('Content-Type','image/png');
        req.setHeader('Content-Length', '0');
        string signature = EncodingUtil.base64Encode(hmac);
        string authHeader =  'SharedKey ' + storageName +':'+signature;
        req.setHeader('Authorization',authHeader);
        req.setEndpoint('https://' + storageName + '.file.core.windows.net/' + shareName + '/'+fileName);
        Http http = new Http();
        HTTPResponse res;
        res = http.send(req);     
        string responseBody = res.getBody();
        system.debug('responseBody--'+responseBody);
    createImage_Put();
    }
}

//Put Range Operation
public void createImage_Put(){

    string storageKey = 'xxxxstorageKeyxxxx';
    string storageName = '<storageName>';
    Datetime dt = Datetime.now();
    string formattedDate = dt.formatGMT('EEE, dd MMM yyyy HH:mm:ss')+ ' GMT';        
    string CanonicalizedHeaders = 'x-ms-date:'+formattedDate+'\nx-ms-range:bytes=0-'+string.valueOf(fileSize)+'\nx-ms-version:2016-05-31\nx-ms-write:update';
    string CanonicalizedResource = '/' + storageName + '/<shareName>/'+fileName+'\ncomp:range';
    string StringToSign = 'PUT\n\n\n'+string.valueOf(fileSize)+'\n\nimage/png\n\n\n\n\n\n\n' + CanonicalizedHeaders+'\n'+CanonicalizedResource;
    system.debug('StringToSign--'+StringToSign);

    Blob temp = EncodingUtil.base64Decode(storageKey);
    Blob hmac = Crypto.generateMac('HmacSHA256',Blob.valueOf(StringToSign),temp ); 
    HttpRequest req = new HttpRequest();
    req.setMethod('PUT');
    req.setHeader('x-ms-version','2016-05-31' );
    req.setHeader('x-ms-date', formattedDate);
    req.setHeader('Content-Length',string.valueOf(fileSize));
    req.setHeader('Content-Type','image/png');
    req.setHeader('x-ms-range','bytes=0-'+string.valueOf(fileSize));
    req.setHeader('x-ms-write','update');
    string signature = EncodingUtil.base64Encode(hmac);
    string authHeader =  'SharedKey '+ storageName+':'+signature;
    req.setHeader('Authorization',authHeader);
    req.setEndpoint('https://storageName.file.core.windows.net/<shareName>/'+fileName+'?comp=range');
    req.setBodyAsBlob(img);
    Http http = new Http();
    HTTPResponse res;
    res = http.send(req);  
    ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.info,'responseBody of PutRange operation--'+res.getBody()));
}
}

In my code, fileName,fileSize,img are the properties of the image i'm trying to upload(which are dynamic).

Here,I'm facing issue with from createImage_Put (PUT RANGE Operation). Below is the error response:

<?xml version="1.0" encoding="utf-8"?>
<Error><Code>InvalidHeaderValue</Code>
<Message>The value for one of the HTTP headers is not in the correct format.
RequestId:0996d8a7-001a-0060-7376-2ce658000000
Time:2017-09-13T09:53:06.4734435Z</Message>
<HeaderName>Content-Length</HeaderName>
<HeaderValue>197844</HeaderValue>
 </Error>

Upvotes: 0

Views: 202

Answers (1)

Gaurav Mantri
Gaurav Mantri

Reputation: 136336

There are a few issues with the code.

  • Because you're simply creating the file, you need not specify the content length of the file in StringToSign. It should be empty.
  • Again because you're creating an empty file, you should not send file data in request body. It should be empty.

Based on these, please see the code below. I was able to run this code and it successfully created an empty file.

public class azure_cls_cpy {
    public string fileName {get; set;}
    public integer fileSize {get; set;}
    public blob img {get; set;}

    public void createImage(){
        string storageKey = 'account-key';
        string storageName = 'account-name';
        string shareName = 'share-name';
        Datetime dt = Datetime.now();
        string formattedDate = dt.formatGMT('EEE, dd MMM yyyy HH:mm:ss')+ ' GMT';
        system.debug('formattedDate--'+formattedDate);
        system.debug('fileSize--'+fileSize);
        integer imageSize = img.size();
        system.debug('imageSize--'+imageSize);
        string CanonicalizedHeaders = 'x-ms-content-length:'+string.valueOf(fileSize)+'\nx-ms-date:'+formattedDate+'\nx-ms-type:file\nx-ms-version:2016-05-31';

        string CanonicalizedResource = '/' + storageName + '/' + shareName + '/' +fileName;
        string StringToSign = 'PUT\n\n\n\n\nimage/png\n\n\n\n\n\n\n' + CanonicalizedHeaders+'\n'+CanonicalizedResource;
        system.debug('StringToSign--'+StringToSign);

        Blob temp = EncodingUtil.base64Decode(storageKey);
        Blob hmac = Crypto.generateMac('HmacSHA256',Blob.valueOf(StringToSign),temp ); 
        HttpRequest req = new HttpRequest();
        req.setMethod('PUT');
        req.setHeader('x-ms-version','2016-05-31' );
        req.setHeader('x-ms-date', formattedDate);
        req.setHeader('x-ms-content-length',string.valueOf(fileSize));
        req.setHeader('x-ms-type','file');
        req.setHeader('Content-Type','image/png');
        req.setHeader('Content-Length', '0');
        string signature = EncodingUtil.base64Encode(hmac);
        string authHeader =  'SharedKey ' + storageName +':'+signature;
        req.setHeader('Authorization',authHeader);
        req.setEndpoint('https://' + storageName + '.file.core.windows.net/' + shareName + '/'+fileName);
        Http http = new Http();
        HTTPResponse res;
        res = http.send(req);     
        string responseBody = res.getBody();
        system.debug('responseBody--'+responseBody);
    }
}

Upvotes: 2

Related Questions