HTTPプロトコルのエラー

この記事では、RFC 2616のエラーだけでなく、HTTPメッセージパーサーの作成方法についても説明し、その長所と短所を示します。 私のアプローチは2つの原則に基づいています。 「1時間を失ってから5分で飛ぶ方が良い」「コンピューターを動作させて休ませる」のです。



したがって、タスク全体としては、特にHTTPサーバー、およびHTTPパーサーを実装します。 プロトコルバージョン1.1はRFC 2616で説明されています。この仕様では、メッセージの構文を定義する物語とBNFの2つのエンティティを区別できます。 BNFルールは十分に形式化されたものであり、RFC 5234でもBNF文法がBNFルールを使用して記述されています。 公表された真実は、RFC 5234がRFC 2616(HTTP)よりも遅く、いくつかの重要でない違いがあります。



BNFショートツアー


BNFの文法は非常に単純なので、例を挙げて説明を行います。これはアイデアを作るのに十分だと思います(慣れていない人のために)。

start-line = Request-Line | Status-Line generic-message = start-line *(message-header CRLF) CRLF [ message-body ]
      
      





ロシア語に翻訳すると、次のことがわかります。

1)start-lineはRequest-LineまたはStatus-Lineです(これらはどこかで説明されているルールでもあります)

2)generic-messageは、開始行、*(メッセージヘッダーCRLF)、CRLF、および場合によってはメッセージ本文のシーケンスです([...]括弧はオプションを定義します)。 *(メッセージヘッダーCRLF)は、2つのメッセージヘッダーとCRLFルールの0回以上の連結の繰り返しを許可します。

正規表現のようなものですが、これは驚くことではありません。



間違いについて


エラーを追跡するために、以下にいくつかのルールを示しました。 それらを簡単に確認すると、次のことがわかります。リクエストは、Request-Lineと、CRLFで区切られたヘッダー(ヘッダー)の繰り返しで構成されています。 ヘッダーグループの中には、entity-headerがあり、general-headerやrequest-headerとは異なり、extension-headerが含まれています。 拡張ヘッダールールは、非標準ヘッダーを許可します。言い換えると、リクエストにヘッダーを追加することを要請するのはそれです
 My-Header: I am server
      
      



ただし、リクエストは引き続き有効です。 さらに、このルールにより、プロトコル拡張を作成する可能性が広がります。 extension-headerは標準ヘッダー(From、Accept、Host、Refererなど)を含むヘッダーを許可するため、この状況が発生します。メッセージに無効な標準ヘッダーが含まれている場合、それを記述するルールでは許可されませんが、extension -headerヘッダーは、それが正しくないことを認めます。

 Request = Request-Line ; Section 5.1 *(( general-header ; Section 4.5 | request-header ; Section 5.3 | entity-header ) CRLF) ; Section 7.1 CRLF [ message-body ] ; Section 4.3 entity-header = Allow ; Section 14.7 | Content-Encoding ; Section 14.11 | Content-Language ; Section 14.12 | Content-Length ; Section 14.13 | Content-Location ; Section 14.14 | Content-MD5 ; Section 14.15 | Content-Range ; Section 14.16 | Content-Type ; Section 14.17 | Expires ; Section 14.21 | Last-Modified ; Section 14.29 | extension-header extension-header = message-header message-header = field-name ":" [ field-value ] field-name = token field-value = *( field-content | LWS ) field-content = <the OCTETs making up the field-value and consisting of either *TEXT or combinations of token, separators, and quoted-string>
      
      





残念ながら、BNFには「他のものを含まないもの」のようなルールを記述する方法がありません。 仕様では、そのようなルールは非公式に説明されています。

 ctext = <any TEXT excluding "(" and ")"> qdtext = <any TEXT except <">>
      
      





正しいフィールド名ルールは次のようになります。

 field-name = <any token excluding "Accept", "Allow", ... all header names from rfc 2616, 2617 ...>
      
      







メインについて


BNFに基づいてDKAを構築するユーティリティについてお話ししたかったのです。 つまり、理想的には、パーサーを自動的に生成します。 しかし、どういうわけか見出しが注目を集めるのに時間がかかりすぎたことが判明したので、次回はツールについて。



UPD :紳士マイナス、ご意見をお聞かせください。 私が間違っている場合、私は何を知りたいです。



All Articles