Python http.clientのHTTPMessageクラスにおけるgetallmatchingheadersメソッドの問題と修正方法

Python 3.9のhttp.clientモジュールに含まれるHTTPMessageクラスのgetallmatchingheadersメソッドに問題が確認されています。公式リポジトリには既にissueが提出されていますが、現時点では修正されていません。 問題のあるコードはhttp/client.pyファイル内のHTTPMessageクラスにあります:
def getallmatchingheaders(self, name):
    """指定されたヘッダー名に一致する全てのヘッダー行を検索します。

    ヘッダーのリストを検索し、指定されたヘッダー名に一致する全ての行
    (およびその継続行)を見つけます。解釈なしに行のリストが返されます。
    ヘッダーが存在しない場合は空のリストが返されます。ヘッダーが複数回
    出現する場合は、全ての出現が返されます。ヘッダー名の大文字小文字は
    区別されません。
    """
    name = name.lower() + ':'
    n = len(name)
    lst = []
    hit = 0
    for line in self.keys():
        if line[:n].lower() == name:
            hit = 1
        elif not line[:1].isspace():
            hit = 0
        if hit:
            lst.append(line)
    return lst
この実装には以下の問題があります: - ヘッダー名にコロンを追加しているため、正確なマッチングが行われない - ヘッダーの値が返されない - keys()メソッドを使用しているため、継続行の処理に問題が生じる 修正後のコード:
def getallmatchingheaders(self, name):
    """指定されたヘッダー名に一致する全てのヘッダー行を検索します。

    ヘッダーのリストを検索し、指定されたヘッダー名に一致する全ての行
    (およびその継続行)を見つけます。解釈なしに行のリストが返されます。
    ヘッダーが存在しない場合は空のリストが返されます。ヘッダーが複数回
    出現する場合は、全ての出現が返されます。ヘッダー名の大文字小文字は
    区別されません。
    """
    name = name.lower()
    n = len(name)
    results = []
    header_active = False
    
    for header_line, header_value in self.items():
        if header_line[:n].lower() == name:
            header_active = True
        elif not header_line[:1].isspace():
            header_active = False
        
        if header_active:
            results.append(f"{header_line}:{header_value}")
    
    return results
主な修正点: - ヘッダー名からコロンを除去 - items()メソッドを使用してヘッダー名と値を取得 - 変数名をより明確に変更 - ヘッダー名と値を結合して返す - 継続行の処理を改善

タグ: Python http.client HTTPMessage bugfix headers

6月3日 20:36 投稿