GNU/Linux >> Tutoriels Linux >  >> Linux

Comment analyser les en-têtes HTTP à l'aide de Bash ?

bash complet la solution. Démontrer comment analyser facilement d'autres en-têtes sans nécessiter 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

Production :

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

Selon la RFC-2616, les en-têtes HTTP sont modélisés comme décrit dans "Standard for the Format of ARPA Internet Text Messages" (RFC822), qui indique clairement la section 3.1.2 :

Le nom du champ doit être composé de caractères ASCII imprimables (c'est-à-dire des caractères dont les valeurs sont comprises entre 33 et 126, décimal, sauf deux-points). Le corps du champ peut être composé de n'importe quel caractère ASCII, sauf CR ou LF. (Bien que CR et/ou LF puissent être présents dans le texte réel, ils sont supprimés par l'action de déplier le champ.)

Ainsi, le script ci-dessus devrait intercepter tout en-tête conforme à la RFC-[2]822 à l'exception notable des en-têtes repliés .


Si vous vouliez extraire plus de quelques en-têtes, vous pouvez placer tous les en-têtes dans un tableau associatif bash. Voici une fonction simple qui suppose qu'un en-tête donné n'apparaît qu'une seule fois. (Ne l'utilisez pas pour Set-Cookie; voir ci-dessous.)

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

Exemple :

$ 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

Notez que la réponse SO inclut un ou plusieurs cookies, en Set-Cookie headers, mais nous ne pouvons voir que le dernier car le script naïf écrase les entrées avec le même nom d'en-tête. (Il se trouve qu'il n'y en avait qu'un mais nous ne pouvons pas le savoir.) Bien qu'il soit possible d'augmenter le script au cas particulier Set-Cookie , une meilleure approche serait probablement de fournir un fichier cookie-jar et d'utiliser le -b et -c curl options afin de le maintenir.


Linux
  1. Comment écrire une boucle dans Bash

  2. Utilisation de mod_cluster dans Apache

  3. Comment utiliser la méthode CONNECT sur un proxy HTTP utilisant Telnet ?

  4. Comment parser un fichier CSV dans Bash ?

  5. Comment parser XML en utilisant shellscript ?

Comment afficher les boîtes de dialogue de l'interface graphique dans le script bash à l'aide de Zenity

Comment changer automatiquement l'arrière-plan de GNOME par intervalles à l'aide de BASH

Bash Scripting - Analyser les arguments dans les scripts Bash à l'aide de getopts

Comment analyser les fichiers CSV dans les scripts Bash sous Linux

Comment exécuter un script bash

Comment créer un proxy HTTP à l'aide de Squid sur CentOS 8