GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cómo analizar encabezados HTTP usando Bash?

Completo bash solución. Demostrar cómo analizar fácilmente otros encabezados sin requerir 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

Produciendo:

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

De acuerdo con RFC-2616, los encabezados HTTP se modelan como se describe en "Estándar para el formato de mensajes de texto de Internet ARPA" (RFC822), que establece claramente la sección 3.1.2:

El nombre del campo debe estar compuesto de caracteres ASCII imprimibles (es decir, caracteres que tienen valores entre 33 y 126, decimal, excepto dos puntos). El cuerpo del campo puede estar compuesto por cualquier carácter ASCII, excepto CR o LF. (Si bien CR y/o LF pueden estar presentes en el texto real, se eliminan al desplegar el campo).

Entonces, el script anterior debería captura cualquier encabezado compatible con RFC-[2]822 con la notable excepción de los encabezados plegados .


Si desea extraer más de un par de encabezados, puede incluir todos los encabezados en una matriz asociativa de bash. Aquí hay una función simple que asume que cualquier encabezado dado solo ocurre una vez. (No lo use para Set-Cookie; ver más abajo.)

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

Ejemplo:

$ 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

Tenga en cuenta que la respuesta SO incluye una o más cookies, en Set-Cookie encabezados, pero solo podemos ver el último porque el script ingenuo sobrescribe las entradas con el mismo nombre de encabezado. (Da la casualidad de que solo había uno, pero no podemos saberlo). Si bien sería posible aumentar la secuencia de comandos al caso especial Set-Cookie , un mejor enfoque probablemente sería proporcionar un archivo de cookies y usar el -b y -c curl opciones para mantenerlo.


Linux
  1. Usando mod_cluster en Apache

  2. ¿Cómo redirigir http a https usando .htaccess?

  3. Cómo agregar encabezados http usando Plesk

  4. ¿Cómo analizar XML usando shellscript?

  5. ¿Cómo escribir un entero en un archivo binario usando Bash?

Cómo mostrar cuadros de diálogo GUI en bash script usando Zenity

Cómo cambiar automáticamente el fondo de GNOME en intervalos usando BASH

Bash Scripting:analizar argumentos en Bash Scripts usando getopts

Cómo analizar archivos CSV en Bash Scripts en Linux

Cómo ejecutar un script Bash

Cómo crear un proxy HTTP usando Squid en CentOS 8