現在、Apigee Edge のドキュメントを表示しています。
Apigee X のドキュメントをご確認ください。 情報
内容
クライアント アプリケーションが、API 呼び出しのレスポンスとして、HTTP ステータス コード 500 Internal Server Error
とエラーコード protocol.http.BadFormData
を受け取ります。
エラー メッセージ
クライアント アプリケーションが次のレスポンス コードを受け取ります。
HTTP/1.1 500 Internal Server Error
また、次のエラー メッセージが表示される場合があります。
{ "fault":{ "faultstring":"Bad Form Data", "detail":{ "errorcode":"protocol.http.BadFormData" } } }
フォームデータ
この問題のトラブルシューティングの詳細に入る前に、フォームデータとは何かを理解しておきましょう。
フォームデータは、通常は、テキスト入力ボックス、ボタン、チェックボックスなどの要素を持つ HTML フォームを介して、ユーザーによって提供される情報です。フォームデータは通常、HTTP リクエストまたはレスポンスの一部として、一連の Key-Value ペアとして送信されます。
フォームデータ転送
- Content-Type: application/x-www-form-urlencoded
- フォームデータのサイズが小さい場合、データは次の要素を含む Key-Value ペアとして送信されます。
- フォーム - セクション 17.13.4.1 で説明されているルールに従ってエンコードされた、両方の鍵の文字
- ヘッダー
Content-Type: application/x-www-form-urlencoded
フォームデータを使用したリクエストの例:
curl https://HOSTALIAS/somepath -H "Content-Type: application/x-www-form-urlencoded" -d "username=abc@google.com&pasword=secret123"
- キーと値の両方に含まれる英数字以外の文字は、
パーセント エンコードされます。つまり、パーセント記号と、特定の文字の ASCII コードを表す 2 つの 16 進数で構成される文字 3 要素
%HH
として表されます。 - したがって、フォームデータではパーセント記号(
%
)を使用できますが、これは特別なエスケープ シーケンスの開始と解釈されます。したがって、フォームデータにキーまたは値にパーセント記号(%
)を含める必要がある場合は、パーセント記号(%
)の ASCII コードを表す%25,
として送信する必要があります。
- フォームデータのサイズが小さい場合、データは次の要素を含む Key-Value ペアとして送信されます。
- Content-Type: multipart/form-data
大量のバイナリデータ、または ASCII 以外の文字を含むテキストを送信する場合は、 フォーム - セクション 17.13.4.2 で説明されているように、
Content-Type:
multipart/form-data を使用してデータを送信できます。
考えられる原因
このエラーは、次のすべての条件が満たされている場合にのみ発生します。
- クライアントが Apigee Edge に送信する HTTP リクエストには、次のものが含まれます。
Content-Type: application/x-www-form-urlencoded
、-
フォーム - セクション 17.13.4.1 で許可されていない 16 進数文字が後にパーセント記号(
%
)またはパーセント記号(%
)の後に続くフォームデータ。
Apigee Edge の API プロキシは、ExtractVariables または AssignMessage ポリシーを使用して、リクエスト フローでの使用が許可されていない文字を含む特定のフォーム パラメータを読み取ります。
たとえば、フォームデータにパーセント記号(
%
)がそのまま(エンコードなし)含まれている場合、またはパーセント記号(%
) の後に無効な 16 進数がキーや値に含まれる場合、このエラーが発生します。このエラーには、次のような原因が考えられます。
原因 説明 トラブルシューティングの実施対象 リクエストのフォーム パラメータに使用できない文字が含まれています クライアントによって HTTP リクエストの一部として渡されるフォーム パラメータに、使用が許可されていない文字が含まれています。 Edge Public Cloud ユーザーと Private Cloud ユーザー
共通の診断手順
このエラーを診断するには、次のいずれかのツールや手法を使用します。
API Monitoring
API Monitoring を使用してエラーを診断するには:
- 適切なロールを持つユーザーとして Apigee Edge UI にログインします。
問題を調査する組織に切り替えます。
- [Analyze] > [API Monitoring] > [Investigate] ページに移動します。
- エラーが発生した期間を選択します。
[Time] に [Fault Code] をプロットします。
次のように、障害コード
protocol.http.BadFormData
を含むセルを選択します。(大きい画像を表示)
障害コード
protocol.http.BadFormData
に関する情報が次のように表示されます。(大きい画像を表示)
[ログを表示] をクリックし、失敗したリクエストの行を開きます。
- [ログ] ウィンドウで、次の詳細をメモします。
- ステータス コード:
500
- 障害ソース:
proxy
- 障害コード:
protocol.http.BadFormData
- 障害ポリシー:
extractvariables/EV-ExtractFormParams
- ステータス コード:
- [Fault Source] が
proxy
、[Fault Code] が [Fault Code] で、[Fault Policy] が空でない場合、Fault Policy で指定された特定のポリシーによる、使用が許可されていない文字を含むフォームデータ(フォーム パラメータ)の読み取りまたは抽出中にエラーが発生したことを示します。protocol.http.BadFormData
- この例では、X-Apigee-fault-policy は
extractvariables/EV- ExtractFormParams,
です。これは、フォーム パラメータの読み取りまたは抽出中に、EV-ExtractFormParams という ExtractVariables ポリシーが失敗したことを意味します。
Trace ツール
Trace ツールを使用してエラーを診断するには:
- トレース セッションを有効にして、次のいずれかを行います。
500 Internal Server Error
エラーが発生するまで待ちます。- 問題を再現できる場合は、API を呼び出して問題を再現します
500 Internal Server Error
[Show all FlowInfos] が有効になっていることを確認します。
- 失敗したリクエストの 1 つを選択し、トレースを調べます。
- トレースのさまざまなフェーズを確認し、エラーが発生した場所を特定します。
このエラーは通常、以下に示すポリシーのいずれかで発生します。
上記のサンプル トレースで、
EV-ExtractFormParams
という名前の Extract Variables ポリシーでエラーが発生したことを確認します。失敗した特定のポリシーの下にある [Error] という名前のフローに移動します。
- トレースで次の値をメモします。
エラー:
Bad Form Data
州:
PROXY_REQ_FLOW
error.class:
com.apigee.rest.framework.BadRequestException
- エラー
Bad Form Data
の値は、フォーム パラメータに使用できない文字が含まれていることを示します。 PROXY_REQ_FLOW,
状態の値は、API プロキシのリクエスト フローでエラーが発生したことを示します。
- エラー
- トレースの [AX(Analytics Data Recorded)] フェーズに移動してクリックします。
[Phase Details] - [Error Headers] セクションまで下にスクロールし、以下のように X-Apigee-fault-code、X-Apigee-fault-source、X-Apigee-fault-policy の値を確認します。
X-Apigee-fault-code と X-Apigee-fault-source の値は、それぞれ
protocol.http.BadFormData
とpolicy
で、X-Apigee-fault-policy は空ではありません。これは、X-Apigee-fault-policy に示された特定のポリシーによる、使用が許可されていない文字を含むフォームデータ(フォーム パラメータ)の読み取りまたは抽出中にエラーが発生したことを示します。レスポンス ヘッダー 値 X-Apigee-fault-code protocol.http.BadFormData
X-Apigee-fault-source policy
X-Apigee-fault-policy extractvariables/EV-ExtractFormParams
- この例では、X-Apigee-fault-policy は
extractvariables/EV- ExtractFormParams,
です。これは、EV-ExtractFormParams
という名前の Extract Variables ポリシーがフォーム パラメータの読み取りまたは抽出中に失敗したことを意味します。
NGINX
NGINX アクセスログを使用してエラーを診断するには:
- Private Cloud ユーザーは、NGINX アクセスログを使用して HTTP
500 Internal Server Error
に関する重要な情報を特定できます。 NGINX のアクセスログを確認します。
/opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log
- 特定の期間にエラーコード
protocol.http.BadFormData
の500
エラーがないか(問題が過去に発生した場合)、または500
で失敗しているリクエストがあるかどうかを検索します。 protocol.http.BadFormData
の値と一致する X-Apigee-fault-code の500
エラーが見つかった場合は、X-Apigee-fault-source と X-Apigee-fault-policy の値を確認します。NGINX のアクセスログの 500 エラーの例:
上記の NGINX アクセスログのエントリ例では、X-Apigee-fault-code と X-Apigee-fault-source に次の値が入っています。
ヘッダー 値 X-Apigee-fault-code protocol.http.BadFormData
X-Apigee-fault-source policy
X-Apigee-fault-policy extractvariables/EV-ExtractFormParams
- X-Apigee-fault-code、X-Apigee-fault-source の値は、それぞれ
protocol.http.BadFormData
、policy
、X-Apigee-fault-policy が空ではないことに注意してください。これは、X-Apigee-fault-policy に示された特定のポリシーが、使用が許可されていない文字を含むフォームデータ(フォーム パラメータ)の読み取りまたは抽出中にエラーが発生したことを示します。X-Apigee-fault-policy,X-Apigee-fault-policy, - この例では、X-Apigee-fault-policy は
extractvariables/EV- ExtractFormParams,
です。これは、EV-ExtractFormParams
という名前の Extract Variables ポリシーがフォーム パラメータの読み取り中に失敗したことを意味します。
原因: リクエストのフォーム パラメータに使用できない文字が含まれています
診断
- 一般的な診断手順で説明されているように、API Monitoring、Trace ツール、または NGINX アクセスログを使用して、
500 Internal Server Error
の障害コード、障害ソース、障害ポリシーを決定します。 - 障害コードが
protocol.http.BadFormData
、障害ソースの値がproxy
またはpolicy
で、障害ポリシーが空でない場合、フォームデータ(フォーム パラメータ)の読み取りまたは抽出中に障害ポリシーで指定されたポリシーが失敗したことを示します。 - [障害ポリシー] に示されているポリシーを調べて、次の情報を特定します。
- ソース: ポリシーがリクエストやレスポンスからデータを読み取っているのか、抽出しているのかを判断します。
- フォーム パラメータ: ポリシーで読み取られる特定のフォーム パラメータを決定します。
サンプル 1
サンプル #1: フォーム パラメータを抽出する ExtractVariables ポリシー:
<ExtractVariables name="EV-ExtractFormParms"> <DisplayName>EV-ExtractFormParams</DisplayName> <Source>request</Source> <FormParam name="username"> <Pattern ignoreCase="false">{username}</Pattern> </FormParam> <FormParam name="password"> <Pattern ignoreCase="false">{password}</Pattern> </FormParam> <VariablePrefix>forminfo</VariablePrefix> <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables> </ExtractVariables>
上記の Extract Variables ポリシーで次の操作を行います。
出典:
request
これは、
<Source>
要素で示されます。フォーム パラメータ:
username
とpassword
これは、
<FormParam>
要素内の<Pattern>
要素で示されます。
これは、クライアントが Apigee Edge に HTTP リクエストの一部として渡すフォーム パラメータ
username
やpassword
に、使用できない文字が含まれていることを示します。サンプル 2
サンプル #2: AssignMessage ポリシーでフォーム パラメータをコピーする
<AssignMessage continueOnError="false" enabled="true" name="AM-CopyFormParams"> <Copy source="request"> <FormParams> <FormParam name="username"/> <FormParam name="password"/> </FormParams> </Copy> <AssignTo createNew="true" transport="http" type="request"/> </AssignMessage>
上記の Extract Variables ポリシーで次の操作を行います。
ソース:
request
これは、
<Copy>
要素のsource
属性で示されます。フォーム パラメータ:
username
とpassword
これは、
<FormParam>
要素のname
属性で示されます。
これは、クライアントが Apigee Edge に HTTP リクエストの一部として渡すフォーム パラメータ
username
またはpassword
、あるいはその両方に、使用できない文字が含まれていることを示します。
次のいずれかの方法で、ステップ 3 で特定したフォーム パラメータに使用できない文字がないかどうかを確認します。
Trace ツール
Trace ツールを使用して検証するには:
- 一般的な診断手順の説明に沿って、失敗したリクエストのトレースをキャプチャした場合は、失敗したリクエストのいずれかを選択します。
- 使用が許可されていない文字を含むフォーム パラメータが、上記のステップ 3 で HTTP リクエストに含まれていると判断した場合は、
- 「Request Received from Client」フェーズに移動します。
[Phase Details] セクションまで下にスクロールし、[Request Content] を確認します。
( 拡大画像を表示)
- 上記の例では、フォーム パラメータ
password
にパーセント記号(%
)が含まれています。 - パーセント記号(
%
)は特殊文字の パーセント エンコードにも使用されるため、フォームデータでそのまま使用することはできません。 - したがって、Apigee Edge は
500 Internal Server Error
というエラーコードprotocol.http.BadFormData
を返します。
実際のリクエスト
実際のリクエストを使用して検証するには:
- ターゲット サーバーに対して行われた実際のリクエストにアクセスできない場合は、解決策に進みます。
- Apigee Edge に対する実際のリクエストにアクセスできる場合は、次の手順を行います。
- フォームデータの内容を確認し、パーセント記号(
%
)やパーセント記号(%
)の後に無効な 16 進数文字など、使用できない文字が含まれていないか確認します。サンプル 1
リクエストの例 1: リクエストに含まれるフォームデータ
curl -X GET "https://HOSTALIAS/myproxy -H "Content-Type: application/x-www-form-urlencoded" -d "client_id=123456abc123&client_secret=c23578%ZY"
この例では、要素
client_secret
にパーセント記号(%
)の後に無効な 16 進数文字ZY
が記述されています。サンプル 2
リクエストの例 2: ファイルで渡されるフォームデータ:
curl -X GET "https://HOSTALIAS/myproxy -H "Content-Type: application/x-www-form-urlencoded" -d @form_data.xml
form_data.xml の内容:
xml=<user><username>abc1234@google.com</username><password>qwerty12345!@#$%</password></user>
この例では、要素
password
にパーセント記号(%
)が含まれていますが、これはフォームデータでそのまま渡すことはできません。
- フォームデータの内容を確認し、パーセント記号(
- 上の 2 つの例では、Apigee Edge への HTTP リクエストの一部として送信されたフォームデータに、使用できない文字が含まれています。
- したがって、Apigee Edge は
500 Internal Server Error
というエラーコードprotocol.http.BadFormData
を返します。
解像度
- クライアントから HTTP リクエストの一部として送信されるフォームデータまたはパラメータのキーと値の両方に含まれる特殊文字が、 フォームデータ - application/x-www-form-urlencoded の説明に従って常にエンコードされるようにします。
- 上記の例では、次の方法で問題を解決できます。
サンプル 1
サンプル #1: リクエストの一部として渡されるフォームデータ:
特定の文字の ASCII コードと一致する有効な 16 進数文字を使用します。たとえば、ドル記号(
$
)を送信する場合は、次のように%24
を使用します。curl -X GET "https://HOSTALIAS/myproxy -H "Content-Type: application/x-www-form-urlencoded" -d "client_id=123456abc123&client_secret=c23578%24"
サンプル 2
リクエストの例 2: ファイルで渡されるフォームデータ:
curl -X GET "https://HOSTALIAS/myproxy -H "Content-Type: application/x-www-form-urlencoded" -d @form_data.xml
form_data.xml の内容:
パーセント(
%
)記号に パーセント エンコードを使用します。これにより、次のように%25
が含まれるようにファイルを変更します。xml=<user><username>abc1234@google.com</username><password>qwerty12345!!@#$%25</password></user>
仕様
Apigee Edge では、フォームデータが次の仕様に従って送信されることを想定しています。
仕様 |
---|
フォームデータ - application/x-www-form-urlencoded |
Apigee サポートのサポートが必要な場合は、診断情報の収集が必要な場合をご覧ください。
診断情報の収集が必要な場合
上記の手順でも問題が解決しない場合は、次の診断情報を収集して Apigee Edge サポートに連絡してください。
Public Cloud ユーザーの場合は、次の情報を入力します。
- 組織の名前
- 環境名
- API プロキシの名前
- エラーコード
protocol.http.BadFormData
とともに500 Internal Server Error
を再現するために使用するcurl
コマンドを完了します。 - API リクエストのトレース ファイル
Private Cloud ユーザーの場合は、次の情報を入力します。
- 失敗したリクエストについて確認された完全なエラー メッセージ
- 環境名
- API プロキシ バンドル
- API リクエストのトレース ファイル
NGINX アクセスログ
/opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log
ここで、ORG、ENV、PORT# は実際の値に置き換えられます。
Message Processor のシステムログ
/opt/apigee/var/log/edge-message-processor/logs/system.log