GNU/Linux >> Linux の 問題 >  >> Linux

Bashを使用してHTTPヘッダーを解析するには?

フル bash 解決。 awk を必要とせずに他のヘッダーを簡単に解析する方法を示します :

shopt -s extglob # Required to trim whitespace; see below

while IFS=':' read key value; do
    # trim whitespace in "value"
    value=${value##+([[:space:]])}; value=${value%%+([[:space:]])}

    case "$key" in
        Server) SERVER="$value"
                ;;
        Content-Type) CT="$value"
                ;;
        HTTP*) read PROTO STATUS MSG <<< "$key{$value:+:$value}"
                ;;
     esac
done < <(curl -sI http://www.google.com)
echo $STATUS
echo $SERVER
echo $CT

プロデュース:

302
GFE/2.0
text/html; charset=UTF-8

RFC-2616 によると、HTTP ヘッダーは 「ARPA インターネット テキスト メッセージのフォーマットの標準」 で説明されているようにモデル化されています。 (RFC822)、セクション 3.1.2 を明確に述べています:

<ブロック引用>

field-name は、印刷可能な ASCII 文字 (コロンを除く 10 進数で 33 から 126 の間の値を持つ文字) で構成する必要があります。フィールド本体は、CR または LF を除く任意の ASCII 文字で構成できます。 (CR および/または LF は実際のテキストに存在する場合がありますが、フィールドを展開するアクションによって削除されます。)

したがって、上記のスクリプトは すべき RFC-[2]822 準拠のヘッダーをキャッチ 折りたたみヘッダーの注目すべき例外 .


2 つ以上のヘッダーを抽出したい場合は、すべてのヘッダーを bash 連想配列に詰め込むことができます。これは、特定のヘッダーが 1 回だけ発生することを前提とする単純な関数です。 (Set-Cookie には使用しないでください);以下を参照してください。)

# Call this as: headers ARRAY URL
headers () {
  {
    # (Re)define the specified variable as an associative array.
    unset $1;
    declare -gA $1;
    local line rest

    # Get the first line, assuming HTTP/1.0 or above. Note that these fields
    # have Capitalized names.
    IFS=$' \t\n\r' read $1[Proto] $1[Status] rest
    # Drop the CR from the message, if there was one.
    declare -gA $1[Message]="${rest%$'\r'}"
    # Now read the rest of the headers. 
    while true; do
      # Get rid of the trailing CR if there is one.
      IFS=$'\r' read line rest;
      # Stop when we hit an empty line
      if [[ -z $line ]]; then break; fi
      # Make sure it looks like a header
      # This regex also strips leading and trailing spaces from the value
      if [[ $line =~ ^([[:alnum:]_-]+):\ *(( *[^ ]+)*)\ *$ ]]; then
        # Force the header to lower case, since headers are case-insensitive,
        # and store it into the array
        declare -gA $1[${BASH_REMATCH[1],,}]="${BASH_REMATCH[2]}"
      else
        printf "Ignoring non-header line: %q\n" "$line" >> /dev/stderr
      fi
    done
  } < <(curl -Is "$2")
}

例:

$ headers so http://stackoverflow.com/
$ for h in ${!so[@]}; do printf "%s=%s\n" $h "${so[$h]}"; done | sort
Message=OK
Proto=HTTP/1.1
Status=200
cache-control=public, no-cache="Set-Cookie", max-age=43
content-length=224904
content-type=text/html; charset=utf-8
date=Fri, 25 Jul 2014 17:35:16 GMT
expires=Fri, 25 Jul 2014 17:36:00 GMT
last-modified=Fri, 25 Jul 2014 17:35:00 GMT
set-cookie=prov=205fd7f3-10d4-4197-b03a-252b60df7653; domain=.stackoverflow.com; expires=Fri, 01-Jan-2055 00:00:00 GMT; path=/; HttpOnly
vary=*
x-frame-options=SAMEORIGIN

SO 応答には、Set-Cookie に 1 つ以上の Cookie が含まれていることに注意してください。 ヘッダーが含まれていますが、単純なスクリプトが同じヘッダー名のエントリを上書きするため、最後のヘッダーしか表示されません。 (たまたま、1 つしかありませんでしたが、それを知ることはできません。)スクリプトを特殊なケース Set-Cookie に拡張することは可能ですが、 、より良いアプローチはおそらくcookie-jarファイルを提供し、 -b を使用することです そして -c それを維持するためのcurlオプション。


Linux
  1. .htaccessを使用してhttpをhttpsにリダイレクトする方法は?

  2. Plesk を使用して http ヘッダーを追加する方法

  3. BashでCSVファイルを解析するには?

  1. bashでインストールを使用してディレクトリをディレクトリにコピーする方法は?

  2. bashスクリプトを使用してcrontabジョブをcrontabに追加するには?

  3. bashコマンドを使用してフォルダを一覧表示するには?

  1. Bashでループを作成する方法

  2. Apacheでmod_clusterを使用する

  3. Telnetを使用してHTTPプロキシでCONNECTメソッドを使用するにはどうすればよいですか?