ここに表示されているのは Apigee Edge のドキュメントです。
Go to the
Apigee X のドキュメントに移動します。 info
症状
クライアント アプリケーションが、API 呼び出しに対するレスポンスとしてエラーコード protocol.http.BadFormData を含む HTTP ステータス コード 500 Internal Server Error を受け取ります。
エラー メッセージ
クライアント アプリケーションは、次のレスポンス コードを受け取ります。
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 進数に続くパーセント記号で構成される文字トリプレット
%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にログインします。
問題を調査する組織に切り替えます。
- [分析] > [API Monitoring] > [調査] ページに移動します。
- エラーが発生した特定の期間を選択します。
[障害コード] を [時間] に対してプロットします。
次のように、障害コード
protocol.http.BadFormDataを含むセルを選択します。(大きい画像を表示)
障害コード
protocol.http.BadFormDataに関する情報が 表示されます。(大きい画像を表示)
[ログを表示] をクリックし、失敗したリクエストの行を展開します。
- [ログ] ウィンドウで、次の詳細をメモします。
- ステータス コード:
500 - 障害の発生源:
proxy - 障害コード:
protocol.http.BadFormData - 障害ポリシー:
extractvariables/EV-ExtractFormParams
- ステータス コード:
- **障害の発生源** が
proxy、**障害コード** がprotocol.http.BadFormData、**障害ポリシー** が空でない場合、**障害ポリシー** で示された特定のポリシーが、使用が**許可されていない** 文字を含むフォームデータ(フォーム パラメータ)を読み取りまたは抽出しているときにエラーが発生したことを示します。 - この例では、X-Apigee-fault-policy は
extractvariables/EV- ExtractFormParams,です。これは、ExtractVariables ポリシー という名前の EV-ExtractFormParams が、フォーム パラメータの読み取りまたは抽出中に失敗したことを意味します。
Trace ツール
Trace ツールを使用してエラーを診断するには:
- トレース セッションを有効にして、
次のいずれかを行います。
500 Internal Server Errorエラーが発生するまで待つ。- 問題を再現できる場合は、API 呼び出しを行って問題を再現する
500 Internal Server Error
[Show all FlowInfos] が有効になっていることを確認します。
- 失敗したリクエストのいずれかを選択し、トレースを調べます。
- トレースのさまざまなフェーズを確認し、エラーが発生した場所を特定します。
通常、エラーは次のようにいずれかのポリシーにあります。
上記のトレース例では、
EV-ExtractFormParamsという名前の ExtractVariables ポリシーでエラーが発生しています。失敗した特定のポリシーの後に、Error という名前のフローに移動します。
- トレースから次の値をメモします。
エラー:
Bad Form Data状態:
PROXY_REQ_FLOWerror.class:
com.apigee.rest.framework.BadRequestException- エラー
Bad Form Dataの値は、フォーム パラメータに使用が許可されていない 文字が含まれていることを示します。 - 状態
PROXY_REQ_FLOW,の値は、 API プロキシの リクエスト フロー でエラーが発生したことを示します。
- エラー
- トレースの [AX](記録された分析データ)フェーズに移動してクリックします。
[**フェーズの詳細**] \- [**エラー ヘッダー**] セクションまでスクロールし、 次のように 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.BadFormDataX-Apigee-fault-source policyX-Apigee-fault-policy extractvariables/EV-ExtractFormParams- この例では、X-Apigee-fault-policy は
extractvariables/EV- ExtractFormParams,です。これは、ExtractVariables ポリシーEV-ExtractFormParamsが、フォーム パラメータの読み取りまたは抽出中に失敗したことを意味します。
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で失敗しているリクエストがまだあるかどうかを確認します。 X-Apigee-fault-code が
protocol.http.BadFormDataの値と一致する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.BadFormDataX-Apigee-fault-source policyX-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 は
extractvariables/EV- ExtractFormParams,です。これは、ExtractVariables ポリシー という名前のEV-ExtractFormParamsが、フォーム パラメータの読み取り中に失敗したことを意味します。
原因: リクエストのフォーム パラメータに許可されていない文字が含まれている
診断
- 共通の診断手順で説明されているように、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>上記の ExtractVariables ポリシーでは:
ソース:
requestこれは
<Source>要素で示されます。フォーム パラメータ:
usernameとpasswordこれは、 要素内の
<Pattern><FormParam>要素で示されます。
これは、クライアントから 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>
上記の ExtractVariables ポリシーでは:
ソース:
requestこれは、
source属性が<Copy>要素で示されます。フォーム パラメータ:
usernameとpasswordこれは、
name属性の<FormParam>要素で示されます。
これは、クライアントから Apigee Edge への HTTP リクエスト の一部として渡されたフォーム パラメータ
usernameまたはpasswordまたは その両方に、使用が許可されていない 文字が含まれていることを示します。
次のいずれかの方法を使用して、ステップ 3 で特定したフォーム パラメータに、使用が許可されていない 文字が含まれているかどうかを確認します。
Trace ツール
Trace ツールを使用して検証するには:
- 共通の診断手順で説明されているように、失敗したリクエストのトレースをキャプチャした場合は、失敗したリクエストのいずれかを選択します。
- ステップ 3 で、使用が許可されていない 文字を含むフォーム パラメータが HTTP リクエストの一部であることが判明した場合は、
- フェーズ [Request Received from Client] に移動します。
[フェーズの詳細] セクションまでスクロールし、 [リクエスト コンテンツ] を確認します。
( 大きい画像を表示)
- 上記の例では、フォーム パラメータ
passwordにパーセント記号(%)が含まれています。 - パーセント記号(
%)は特殊文字の パーセント エンコードにも使用されるため、フォームデータでそのまま使用することはできません。 - そのため、Apigee Edge はエラーコード
protocol.http.BadFormDataを含む500 Internal Server Errorを返します。
実際のリクエスト
実際のリクエストを使用して検証するには:
- ターゲット サーバーに対して行われた実際のリクエストにアクセスできない場合は、 解決策に進みます。
- 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 はエラーコード
protocol.http.BadFormDataを含む500 Internal Server Errorを返します。
解決策
- クライアントから 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