2017-09-11 12 views
0
のREST API-無効なヘッダー値「のContent-Length」を使用して、ファイルサービス/アズールで画像を

更新: https://docs.microsoft.com/en-us/rest/api/storageservices/put-range私はここで指定されたREST APIドキュメントを使用してAzureの中でファイルサービスに画像をアップロードしようとしている

視覚的な力は、ページ:

<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);     
} 

、ファイル名、ファイルサイズ、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()に戻してください。

+0

を。私は 'CanonicalizedHeaders'にヘッダーがいくつか見えています。それは、 'x-ms-'で始まるすべてのリクエストヘッダを含むべきです。私は強くお勧めします(むしろ謝辞:))、このページ:https://docs.microsoft.com/en-us/rest/api/storageservices/authentication-for-the-azure-storage-services。ここで概説した概念を理解したら、REST APIに問題はないはずです。 –

+0

したがって、あなたのリクエストに 'Content-Length'ヘッダを指定するだけでなく、stringToSignを計算するときも同じことを考慮する必要があります。今私はそれがあなたのstringToSignに含まれていないことを見ている。それを戻し、それに応じて質問を編集してください。 –

+0

あなたはどの言語を使用していますか?この環境を構築するのに役立つHTTPクライアントクラスがありますか?あなたのコードにはHTTPリクエストをまとめることからくる複雑さがたくさんあるようです。それを行う簡単な方法があるはずです。 –

答えて

2

私はすぐに問題を見たはずです。基本的に問題はx-ms-rangeヘッダーにありました。 0から始まるため、終了値はlength of the image - 1である必要があります。一度これを行うと、コードは正常に動作するはずです。

以下のコードを参照してください:私はあなた `CanonicalizedResource`は大丈夫だと思う

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); 
    } 
} 
+0

このシナリオではすでにヒットしました。そのような場合、その 'ResourceNotFound'例外をスローする – Rv1

+0

これに関するあなたの他の質問で私のコメントを参照してください。 –

2

Content-Length値が予期しないエラーが発生しています。送信しているペイロードが2224バイトに一致していない可能性があります。 setBodyAsBlobが実際に2224バイトのデータを送信しているかどうかを確認します。 WireSharkのようなツールでこのキャプチャパケットを確認できます。

+0

どんなヘルプ@sguler。私はblobをEncodingUtil.base64Encodeに変換して、リクエストで送信されたバイト数を確認しました。それは正常に動作しています。他のアイデア – Rv1

+0

申し訳ありません - 考えません。私はJavaで私に起こったのと全く同じエラーが発生しました。ここで送信されたバイトはcontent-lengthと一致しませんでした。たとえそれが1バイトオフであっても、サーバーはあなたの要求に失敗します。私は強くFiddlerまたはWireSharkからワイヤー上のバイトを実際にチェックすることを強くお勧めします。 Btw - 代わりに、既存のAzure Storage Client Librariesを使用してみませんか? – sguler

+0

salesforceでは、javaなどの既存のライブラリを使用するオプションはありません。私はFiddlerやwiresharkの機能を知らない。 Btw-どのようにJavaでバイト範囲の違いの問題を解決しましたか? – Rv1

関連する問題

 関連する問題