GNU/Linux >> Belajar Linux >  >> Linux

Bagaimana cara mengurai header HTTP menggunakan Bash?

Penuh bash larutan. Peragakan cara mengurai header lain dengan mudah tanpa memerlukan 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

Memproduksi:

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

Menurut RFC-2616, header HTTP dimodelkan seperti yang dijelaskan dalam "Standar untuk Format Pesan Teks Internet ARPA" (RFC822), yang menyatakan dengan jelas bagian 3.1.2:

Nama bidang harus terdiri dari karakter ASCII yang dapat dicetak (yaitu, karakter yang memiliki nilai antara 33. dan 126., desimal, kecuali titik dua). Bidang-badan dapat terdiri dari karakter ASCII apa saja, kecuali CR atau LF. (Meskipun CR dan/atau LF mungkin ada dalam teks sebenarnya, mereka dihapus dengan tindakan membuka bidang.)

Jadi skrip di atas harus tangkap header apa pun yang sesuai dengan RFC-[2]822 dengan pengecualian header terlipat .


Jika Anda ingin mengekstrak lebih dari beberapa header, Anda bisa memasukkan semua header ke dalam array asosiatif bash. Inilah fungsi berpikiran sederhana yang mengasumsikan bahwa setiap tajuk yang diberikan hanya muncul sekali. (Jangan gunakan untuk Set-Cookie; lihat di bawah.)

# 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")
}

Contoh:

$ 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

Perhatikan bahwa respons SO menyertakan satu atau lebih cookie, di Set-Cookie header, tetapi kita hanya dapat melihat yang terakhir karena skrip naif menimpa entri dengan nama header yang sama. (Kebetulan, hanya ada satu tetapi kami tidak dapat mengetahuinya.) Meskipun dimungkinkan untuk menambah skrip ke kasus khusus Set-Cookie , pendekatan yang lebih baik mungkin adalah menyediakan file cookie-jar, dan menggunakan -b dan -c opsi curl untuk mempertahankannya.


Linux
  1. Cara menulis loop di Bash

  2. Bagaimana cara mengarahkan ulang http ke https menggunakan .htaccess?

  3. Bagaimana cara mendaftar folder menggunakan perintah bash?

  1. Menggunakan mod_cluster di Apache

  2. Bagaimana cara menambahkan header http menggunakan Plesk

  3. Bagaimana cara mengurai file CSV di Bash?

  1. Bagaimana cara mem-parsing XML menggunakan shellscript?

  2. Bagaimana cara menulis integer ke file biner menggunakan Bash?

  3. Bagaimana cara menyalin direktori ke direktori menggunakan install di bash?