このトピックでは、アップロード操作のコールバック関数の一般的なエラーとその処理方法について説明します。
アップロードコールバックについて
ファイルがアップロードされると、OSSはコールバックをコールバックサーバーに提供できます。 アップロードコールバックを実装するには、アップロードリクエストに関連するコールバックパラメーターを含めることができます。 アップロードコールバックをサポートするAPIは、PutObject、PostObject、およびCompleteMultipartUploadです。 詳細については、開発者ガイドの「アップロードコールバック」および「コールバックAPI」をご参照ください。
コールバックサーバーはサービスサーバーとも呼ばれます。
適用シナリオ
お知らせ
典型的なアプリケーションは、ファイルアップロード中にコールバックパラメータを指定する許可された第三者によるアップロードおよびコールバックである。 アップロードが完了すると、OSSはコールバックサーバーにコールバック要求を送信します。 コールバック要求を受信すると、コールバックサーバはアップロード情報を記録する。
処理、レビュー、および統計
コールバックリクエストを受信すると、コールバックサーバーはアップロードされたファイルを処理、レビュー、統計します。
データストリーム
パラメーターについて、次のテーブルで説明します。
データストリーム | 意味 | 説明 |
1 | クライアントはファイルをアップロードし、コールバックパラメーターを保持します。 形式の詳細については、「SDK/PostObject」をご参照ください。 | アップロード は SDK (PutObject と CompleteMultipartUpload) によって実装され、コールバックは PostObject API によって実装されます。 |
2 | OSS インスタンスはファイルを保存し、コールバックを開始します。 | OSSインスタンスは、アップロードリクエストで指定された POSTリクエストの形式の詳細については、「コールバックリクエストの開始」をご参照ください。 |
3 | コールバックサーバーは処理結果を返します。 |
|
4 | OSS はアップロードとコールバックの結果を返します。 |
|
SDK / PostObject
ファイルのアップロード中に、コールバックパラメーターを設定して、コールバックサーバーのURL、コールバックサーバーに送信するデータ、およびデータ形式を指定できます。 コールバックサーバーがコールバックを処理すると、バケット
やオブジェクト
などのコンテキスト情報がシステム変数を使用して指定されます。 他のコンテキスト情報はカスタム変数を使用して指定されます。
アップロードコールバックには、以下のパラメーターが使用できます。
フィールド | 意味 | 説明 |
callbackUrl | コールバックサーバーのアドレス | 必須/任意 |
callbackHost | コールバック要求メッセージヘッダ内の | オプションです。 デフォルト値は |
callbackBody | コールバック要求のメッセージ本文 | 必須。 システム変数とカスタム変数を保持できます。 |
callbackBodyType | コールバックリクエストメッセージヘッダーの | オプションです。 |
アップロードコールバックパラメーターは、次の 2 つの方法のいずれかのアップロード要求によって伝送されます。
コールバックパラメーターは、メッセージヘッダーの
x-oss-callback
によって伝達されます。 これは一般的かつ推奨されている方法です。コールバックパラメーターは、QueryStringの
callback
によって運ばれます。
x-oss-callback
またはcallback
値を生成するためのルールは次のとおりです。
コールバック:= Base64(CallbackJson)
CallbackJson := '{' CallbackUrlItem, CallbackBodyItem [, CallbackHostItem, CallbackBodyTypeItem] '}'
CallbackUrlItem := '"'callbackUrl'"':'"'CallbackUrlValue'"'
CallbackBodyItem := '"'callbackBody'"':'"'CallbackBodyValue'"'
CallbackHostItem := '"'callbackHost'"':'"'CallbackHostValue'"'
CallbackBodyTypeItem := '"'callbackBodyType'"' : '"'CallbackBodyType'"'
CallbackBodyType := application/x-www-form-urlencoded | application/json
CallbackJson
の値の例は次のとおりです。
"callbackUrl" : "http://abc.com/test.php",
"callbackHost" : "oss-cn-hangzhou.aliyuncs.com",
"callbackBody" : "{\" bucket\":${ bucket}, \" object\":${ object },\" size\":${ size },\" mimeType\":${ mimeType },\" my_var\":${ x:my_var}}" 、
"callbackBodyType" : "application/json"
または
"callbackUrl" : "http://abc.com/test.php",
"callbackBody" : "bucket=${bucket}&object=${object}&etag=${etag}&size=${size}&mimeType=${mimeType}&my_var=${x:my_var}"
システム変数とカスタム変数
CallbackJson
の例の ${bucket}
、${object}
、${size}
などのCallbackJson
の変数は、OSSで定義されたシステム変数です。 コールバック中に、OSSはシステム変数を実際の値に置き換えます。 次の表に、OSSで定義されたシステム変数を示します。
変数 | 意味 |
${bucket} | ストレージスペース名 |
${object} | ファイル名 |
${etag} | ファイルのタグ |
${size} | ファイルサイズ |
${mimeType} | image / jpeg などのファイルタイプ |
$ {imageInfo.height} | イメージの高さ |
$ {imageInfo.width} | イメージの幅 |
$ {imageInfo.format} | .jpgや.pngなどのイメージフォーマット |
システム変数は大文字と小文字を区別します。
システム変数は
${bucket}
形式です。imageInfo はイメージ形式を対象に設定されます。 非イメージ形式の場合、imageInfo の値は空白です。
CallbackJson
の例では、${x:my_var}
などのCallbackJson
の変数がカスタム変数です。 コールバック中に、OSSはカスタム変数をカスタム値に置き換えます。 カスタム変数値は、次の 2 つの方法のいずれかにより、アップロード要求によって定義され、伝送されます。
カスタム変数は、メッセージヘッダーの
x-oss-callback-var
によって運ばれます。 これは一般的かつ推奨されている方法です。カスタム変数は、QueryStringの
callback-var
によって運ばれます。
x-oss-callback-var
またはcallback-var
値を生成するためのルールは次のとおりです。
CallbackVar := Base64(CallbackVarJson)
CallbackVarJson := '{' CallbackVarItem [, CallbackVarItem]* '}'
CallbackVarItem := '"'x:'VarName'"' : '"'VarValue'"'
CallbackVarJson
の値の例は次のとおりです。
"x:my_var1" : "value1",
"x:my_var2" : "value2"
カスタム変数はx: で始まる必要があります。これらは大文字と小文字が区別され、
${x:my_var}
の形式です。カスタム可変長は、メッセージヘッダーと URL の長さによって制限されます。 カスタム変数の数は 10 個を超えないようにし、合計長は 512 バイトを超えないようにすることを推奨します。
SDK の使用例
JAVA や JS などの一部の SDK では、上記の手順がカプセル化されています。 Python、PHP、Cなどの一部のSDKは、上記のルールを使用してアップロードコールバックパラメーターとカスタム変数を生成する必要があります。 次のテーブルにて、SDK の使用例を一覧表示します。
SDK | アップロードコールバックの例 | 説明: |
JAVA |
| |
Python | - | |
PHP | $optionsの | |
C # | using to read | |
JS | - | |
C | - | |
Ruby | - | |
iOS |
| |
Android |
|
Go SDK は現在アップロードコールバックをサポートしていません。
PostObject の使用例
PostObjectはアップロードコールバックをサポートしており、そのコールバックパラメーターはフォームフィールドのコールバック
によって運ばれ、カスタム変数は独立したフォームフィールドによって運ばれます。 詳細については、「PostObjet」をご参照ください。
PostObject の使用例を次のテーブルに示します。
SDK | アップロードコールバックの例 |
Java | |
Python | |
C# |
コールバックサーバー
コールバックサーバーは、OSSから送信されたコールバック要求とPOSTメッセージを処理するHTTPサーバーです。 コールバックサーバーURLは、アップロードコールバックパラメーターcallbackUrl
の値です。 アップロードされたデータの記録、レビュー、処理、および統計のために、コールバックサーバーに独自の処理ロジックを実装できます。
コールバック署名
コールバックサーバーは、POSTリクエストがOSSアップロードコールバックからのものであることを確認するために、POSTリクエストの署名を検証する必要があります。 コールバックサーバーは、署名を検証せずにメッセージを直接処理することもできます。 コールバックサーバーのセキュリティを強化するために、コールバックサーバーがメッセージ署名を検証することを推奨します。 コールバック署名ルールの詳細については、「コールバック署名」をご参照ください。
OSSコールバックサーバーの例では、署名検証の実装方法について説明します。 コードを直接使用することを推奨します。
メッセージ処理
コールバックサーバーの主なロジックは、OSSコールバックリクエストを処理することです。 次の点に注意してください。
コールバックサーバーは OSS の POST 要求を処理する必要があります。
OSS コールバックのタイムアウト時間は 5 秒です。 したがって、コールバックサーバーは5秒以内に処理を完了し、結果を返す必要があります。
コールバックサーバーからOSSに送信されるメッセージ本文は、JSON形式である必要があります。
コールバックサーバーは独自のロジックを使用し、OSSは特定のサービスロジックの代わりに例を提供します。
実装例
次のテーブルは、コールバックサーバーの実装例を示しています。
Language | 例 | 実行方法 |
JAVA | パッケージを解凍し、 | |
PHP | Apache環境でプログラムをデプロイして実行します。 | |
Python | パッケージを解凍し、 | |
Ruby |
|
デバッグ手順
アップロードコールバックデバッグには、ファイルをアップロードするクライアントと、コールバックを処理するコールバックサーバーのデバッグが含まれます。 最初にクライアントをデバッグし、次にコールバックサーバーをデバッグすることをお勧めします。 2つの部分を個別にデバッグした後、完全なアップロードコールバックを実行します。
クライアントのデバッグ
OSSが提供するコールバックサーバー
http://oss-demo.aliyuncs.com:23450
、つまりコールバックパラメーターcallbackUrl
を使用してクライアントをデバッグできます。 コールバックサーバーは、コールバック要求の署名のみを検証し、コールバック要求を処理しません。 署名が正常に検証されたコールバック要求の場合、コールバックサーバーは{"Status":"OK"}
を返します。 署名の検証に失敗したコールバック要求の場合、コールバックサーバーは400 Bad Request
を返します。 非POST要求の場合、コールバックサーバーは501サポートされていないメソッド
を返します。 コールバックサーバーの例のコードの詳細については、「callback_app_server.py.zip」をご参照ください。コールバックサーバーのデバッグ
コールバックサーバーは POST 要求を処理できる HTTP サーバーです。 OSS によって提供される例に基づいてコールバックサーバーを修正するか、または自分で実装することができます。 次のテーブルで、OSS によって提供されるコールバックサーバーの例を示します。
Language
例
実行方法
JAVA
パッケージを解凍し、
java -jar oss-callback-server-demo.jar 9000
を実行します。PHP
Apache環境でプログラムをデプロイして実行する
Python
パッケージを解凍し、
python callback_app_server.py
を実行します。C#
プログラムをコンパイルして実行し
aliyun-oss-net-callback-server.exe 127.0.0.1 80
。Go
プログラムをコンパイルし、
aliyun_oss_callback_server
を実行します。Ruby
ruby aliyun_oss_callback_server.rb
を実行します。コールバックサーバーは、cURL コマンドを実行することでデバッグできます。 以下は実際に使用される可能性のある cURL コマンド文です。
# 次のコマンドを実行して、メッセージ本文が 'object=test_obj 'である 'POST' リクエストをコールバックサーバーに送信します。curl -d "object=test_obj" http://oss-demo.aliyuncs.com:23450 -v # 次のコマンドを実行して、メッセージ本文が 'post.txt 'である 'POST' リクエストをコールバックサーバーに送信します。curl -d @ post.txt http://oss-demo.aliyuncs.com:23450 -v # 次のコマンドを実行して、メッセージ本文が 'post.txt 'で、指定されたメッセージヘッダー 'Content-Type' を保持する 'POST' リクエストをコールバックサーバーに送信します。curl -d @ post.txt -H "コンテンツタイプ: application/json" http://oss-demo.aliyuncs.com:23450 -v
説明コールバックサーバーをデバッグするときは、
cURL
が署名関数をシミュレートするのが難しいため、署名検証を無視してください。OSS の例では、署名検証関数を提供しています。 直接使用することを推奨します。
デバッグと追跡を容易にするため、コールバックサーバーにすべてのメッセージを記録するログ機能を実装することを推奨します。
コールバック要求を正しく処理した後、コールバックサーバーは20倍ではなく
200
を返す必要があります。コールバックサーバーからOSSに送信されるメッセージ本文はJSON形式である必要があり、
Content-Type
はapplication/json
に設定されています。
一般的なエラーと原因
InvalidArgument
<エラー> <Code>InvalidArgument</Code> <Message> コールバック設定はjson形式ではありません。</Message> <RequestId>587C79A3DD373E2676F73ECE</RequestId> <HostId>bucket.oss-cn-hangzhou.aliyuncs.com</HostId> <ArgumentName>callback</ArgumentName> <ArgumentValue>{"callbackUrl":"8.8.8.8:9090","callbackBody":"{" bucket ":${ bucket}," object ":${ object}}","callbackBodyType":"application/json"}</ArgumentValue> </エラー>
説明コールバックパラメーターの設定が正しくないか、パラメーターの形式が正しくありません。 一般的なエラーは、
ArgumentValue
のコールバックパラメーターが有効なJSON形式ではないことです。 JSONでは、\
と"
はエスケープ文字です。 たとえば、"callbackBody":"{" bucket ":${ bucket}," object ":${ object}}"
は"callbackBody":"{\" bucket\":${ bucket },\" object\":${ object}}"
である必要があります。 SDKの詳細については、SDKの使用例のアップロードコールバックの例をご参照ください。キャラクター後の脱出
キャラクター前エスケープ
\\
\\\\
“
\\\”
\b
\\b
\f
\\f
\n
\\n
\r
\\r
\t
\\t
CallbackFailed
CallbackFailedエラーの例は次のとおりです。
例 1
<エラー> <Code>CallbackFailed</Code> <メッセージ> レスポンスボディが有効なjson形式ではありません。</Message> <RequestId>587C81A125F797621829923D</RequestId> <HostI d>bucket.oss-cn-hangzhou.aliyuncs.com</HostId> </エラー>
説明コールバックサーバーからOSSに送信されるメッセージ本文はJSON形式ではありません。
curl -d "<content>" <CallbackServerURL> -v
を実行するか、パケットをキャプチャしてコンテンツを確認できます。 WindowsではWiresharkを使用してパケットをキャプチャし、Linuxではtcpdumpを使用してパケットをキャプチャすることを推奨します。 返された無効なメッセージには、OK
と\357\273\277{"Status":"OK"}
(ef bb bf
バイトを含むBOMヘッダー) が含まれます。例 2
<エラー> <Code>CallbackFailed</Code> <Message>Error status : -1. OSSはcallbackUrlに接続できません。確認してください。</Message> <RequestId>587C8735355BE8694A8E9100</RequestId> <HostI d>bucket.oss-cn-hangzhou.aliyuncs.com</HostId> </エラー>
説明コールバックサーバーの処理時間が 5 秒を超過しています。 したがって、OSS はタイムアウトが発生したと判断します。 5 秒以内に処理を完了し、結果を OSS に返すことができるように、コールバックサーバーの処理ロジックを非同期処理に変更することを推奨します。
例 3
<エラー> <Code>CallbackFailed</Code> <Message> error status:-1 8.8.8.8: 9090 reply timeout, cost: 5000 MS, timeout: 5000 MS (Ernest-4, errno170) </message> <RequestId>587C8D382AE0B92FA3EEF62C</RequestId> <HostI d>bucket.oss-cn-hangzhou.aliyuncs.com</HostId> </エラー>
説明コールバックサーバーの処理時間が 5 秒を超過しています。 したがって、OSS はタイムアウトが発生したと判断します。
例 4
<エラー> <Code>CallbackFailed</Code> <メッセージ> エラーステータス: 400。</Message> <RequestId>587C89A02AE0B92FA3C7981D</RequestId> <HostI d>bucket.oss-cn-hangzhou.aliyuncs.com</HostId> </エラー>
説明コールバックサーバーからOSSに送信されるメッセージのステータスコードが
400
されています。 コールバックサーバーの処理ロジックを確認します。例 5
<エラー> <Code>CallbackFailed</Code> <メッセージ> エラーステータス: 502。</Message> <RequestId>587C8D382AE0B92FA3EEF62C</RequestId> <HostI d>bucket.oss-cn-hangzhou.aliyuncs.com</HostId> </エラー>
説明コールバックサーバーが起動されていないか、
CallbackUrl
がコールバックパラメーターにないか、OSSインスタンスとコールバックサーバー間のネットワークが切断されています。 トラフィックコストを節約し、ネットワーク品質を保証するため、コールバックサーバーを OSS と同じイントラネットに属する ECS に配置することを推奨します。
レスポンスの本文がJSON形式ではありません。
設定例:
このエラーは、次の理由が原因である可能性があります。
次の図に示すように、アプリケーションサーバーからOSSに返されるレスポンスの本文がJSON形式ではありません。
resp_bodyが有効なJSON形式でない場合、OSSはエラーを報告します。 さらに、このエラーは、例外のためにアプリケーションサーバーがOSSへの通常の応答の代わりにスタックトレースを返すなど、他の根本的な要因によって引き起こされる可能性があります。
アプリケーションサーバーからOSSに返されるレスポンスの本文には、ヘッダーにBOMが含まれています。
この問題は通常、PHPでコーディングされたアプリケーションサーバーで発生します。このサーバーには、OSSに返される応答にBOMヘッダーが含まれています。 したがって、JSON形式に準拠していない3つの追加バイト (つまり、BOMヘッダー) がレスポンスに含まれているため、OSSはエラーを報告します。 次の図は、アプリケーションサーバーが送信するパケットに含まれる内容を示しています。
上の図では、
ef bb bf
バイトはBOMヘッダーの3つの追加バイトです。説明この問題を解決するには、アプリケーションサーバーからOSSに返されるレスポンスのBOMヘッダーを削除します。
エラーステータス
次の図に示すように、502や400などのエラーステータスコードは、不正なコールバック関数が原因で返されるエラーです。
説明アプリケーションサーバーからOSSに返されたHTTPステータスを示すために、400、404、403などのエラーステータスコードが返されます。 ステータスコード200の戻りは、動作が成功したことを示す。
アプリケーションサーバーでWebサービスが有効になっていない場合、エラー状態コード502が返されます。つまり、サーバーはOSSから送信されたコールバック要求を受信できません。
タイムアウト
タイムアウトエラーを次の図に示します。
説明セキュリティ上の理由から、OSSはコールバック応答の受信を最大5秒間待機します。 応答が返されない場合、OSSはアプリケーションサーバーから切断され、クライアントにタイムアウトエラーが返されます。 エラーメッセージに含まれるIPアドレスは無視できます。