GNU/Linux >> Linux Esercitazione >  >> Linux

Come analizzare le intestazioni HTTP usando Bash?

Completo bash soluzione. Dimostra come analizzare facilmente altre intestazioni senza richiedere 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

Produzione:

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

Secondo RFC-2616, le intestazioni HTTP sono modellate come descritto in "Standard per il formato dei messaggi di testo Internet ARPA" (RFC822), che afferma chiaramente la sezione 3.1.2:

Il nome-campo deve essere composto da caratteri ASCII stampabili (ovvero caratteri con valori compresi tra 33. e 126., decimali, eccetto i due punti). Il corpo del campo può essere composto da qualsiasi carattere ASCII, tranne CR o LF. (Anche se CR e/o LF possono essere presenti nel testo vero e proprio, vengono rimossi dall'azione di dispiegamento del campo.)

Quindi lo script precedente dovrebbe rilevare qualsiasi intestazione conforme a RFC-[2]822 con la notevole eccezione delle intestazioni ripiegate .


Se si desidera estrarre più di un paio di intestazioni, è possibile inserire tutte le intestazioni in un array associativo bash. Ecco una semplice funzione che presuppone che ogni data intestazione si verifichi solo una volta. (Non usarlo per Set-Cookie; vedi sotto.)

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

Esempio:

$ 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

Tieni presente che la risposta SO include uno o più cookie, in Set-Cookie intestazioni, ma possiamo vedere solo l'ultima perché lo script ingenuo sovrascrive le voci con lo stesso nome di intestazione. (Si dà il caso che ce n'era solo uno, ma non possiamo saperlo.) Mentre sarebbe possibile aumentare lo script al caso speciale Set-Cookie , un approccio migliore sarebbe probabilmente quello di fornire un file cookie-jar e utilizzare il -b e -c curl opzioni per mantenerlo.


Linux
  1. Come scrivere un ciclo in Bash

  2. Come utilizzare il metodo CONNECT su un proxy HTTP utilizzando Telnet?

  3. Come reindirizzare da http a https usando .htaccess?

  4. Come aggiungere intestazioni http utilizzando Plesk

  5. Come analizzare XML usando shellscript?

Come visualizzare le finestre di dialogo della GUI nello script bash usando Zenity

Come modificare automaticamente lo sfondo di GNOME a intervalli utilizzando BASH

Bash Scripting – Analizza gli argomenti negli script Bash usando getopts

Come analizzare i file CSV negli script Bash in Linux

Come eseguire uno script Bash

Come creare un proxy HTTP utilizzando Squid su CentOS 8