使用REST API更新文件服务/ Azure中的图像 - 无效的标头值'Content-Length'

时间:2017-09-11 11:10:11

标签: rest azure azure-files

我正在尝试使用此处指定的REST API文档将图像上传到Azure中的FILE SERVICE: https://docs.microsoft.com/en-us/rest/api/storageservices/put-range

视觉力页面:

<apex:page controller="azure_cls_cpy">
<apex:form >
    <apex:inputFile value="{!img}" filename="{!fileName}" fileSize="{!fileSize}" ></apex:inputFile>
    <apex:commandButton value="Click" action="{!createImage}"/><br/>
    <apex:messages />
</apex:form>
</apex:page>

这是我的代码,它不起作用:

public void createImage(){
    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>/<DirectoryName>/'+fileName+'\ncomp:range\ntimeout:20';
        string StringToSign = 'PUT\n\n\nstring.valueOf(fileSize)\n\n\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 ); //StringToSign
    system.debug('oo-'+EncodingUtil.base64Encode(hmac));
    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('x-ms-range','bytes=0-'+string.valueOf(fileSize));        
    req.setHeader('x-ms-write','update');
    string signature = EncodingUtil.base64Encode(hmac);
    string authHeader =  'SharedKey biznussoftfiles'+':'+signature;

    req.setHeader('Authorization',authHeader);
    req.setEndpoint('https://<storageName>.file.core.windows.net/<shareName>/<directoryName>/'+fileName+'?comp=range&timeout=20');
    req.setBodyAsBlob(img);              
    Http http = new Http();
    HTTPResponse res;
    res = http.send(req);                
}

在我的代码中,fileName,fileSize,img是我试图上传的图片的属性(动态)。

在这里,我面临Content-Length的问题。以下是错误回复:

<?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>

更新注意:将范围恢复为0-filesize()以避免无效范围错误。

2 个答案:

答案 0 :(得分:2)

您获得的错误表明Content-Length值是意外的。您发送的有效负载可能与2224字节不匹配。检查setBodyAsBlob是否真的发送2224字节的数据。您可以在WireShark等工具上验证此捕获数据包。

答案 1 :(得分:2)

我应该早点看到这个问题:)。问题基本上是你的x-ms-range标题。因为它从0开始,所以结束值应为length of the image - 1。一旦你这样做,代码应该可以正常工作。

请参阅以下代码:

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);
        string CanonicalizedHeaders = 'x-ms-date:'+formattedDate+'\nx-ms-range:bytes=0-'+string.valueOf(fileSize-1)+'\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\n\n\n\n\n\n\n\n' + CanonicalizedHeaders+'\n'+CanonicalizedResource;
        system.debug('StringToSign--'+StringToSign);

        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-range','bytes=0-'+string.valueOf(fileSize-1));
        req.setHeader('x-ms-write','update');
        req.setHeader('Content-Length', string.valueOf(fileSize));
        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);     
        string responseBody = res.getBody();
        system.debug('responseBody--'+responseBody);
    }
}