Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to retrieve the real redirect location header with Curl? without using {redirect_url}

I realized that Curl {redirect_url} does not always show the same redirect URL. For example if the URL header isLocation: https:/\example.com this will redirect to https:/\example.com but curl {redirect_url} shows redirect_url: https://host-domain.com/https:/\example.com and it won't display the response real location header. (I like to see the real location: result.)

This is the BASH I'm working with:

#!/bin/bash
# Usage: urls-checker.sh domains.txt
FILE="$1"
while read -r LINE; do
     # read the response to a variable
     response=$(curl -H 'Cache-Control: no-cache' -s -k --max-time 2 --write-out '%{http_code} %{size_header} %{redirect_url} ' "$LINE")
     # get the title
     title=$(sed -n 's/.*<title>\(.*\)<\/title>.*/\1/ip;T;q'<<<"$response")
     # read the write-out from the last line
     read -r http_code size_header redirect_url < <(tail -n 1 <<<"$response")
     printf "***Url: %s\n\n" "$LINE"
     printf "Status: %s\n\n" "$http_code"
     printf "Size: %s\n\n" "$size_header"
     printf "Redirect-url: %s\n\n" "$redirect_url"
     printf "Title: %s\n\n" "$title"
     # -c 20 only shows the 20 first chars from response
     printf "Body: %s\n\n" "$(head -c 100 <<<"$response")"
done < "${FILE}"

How can I printf "Redirect-url: the original requested location: header without having to use redirect_url?

like image 359
pancho Avatar asked Sep 30 '17 21:09

pancho


People also ask

How do I get the header info from curl?

We can use curl -v or curl -verbose to display the request headers and response headers in the cURL command. The > lines are request headers .

How do I redirect a curled URL?

To follow redirect with Curl, use the -L or --location command-line option. This flag tells Curl to resend the request to the new address. When you send a POST request, and the server responds with one of the codes 301, 302, or 303, Curl will make the subsequent request using the GET method.

What is HTTP Location header?

The HTTP Location header is a response header that is used under 2 circumstances to ask a browser to redirect a URL (status code 3xx) or provide information about the location of a newly created resource (status code of 201). Its usage is often confused with another HTTP Header which is HTTP Content-Location header.


2 Answers

To read the exact Location header field value, as returned by the server, you can use the -i/--include option, in combination with grep.

For example:

$ curl 'http://httpbin.org/redirect-to?url=http:/\example.com' -si | grep -oP 'Location: \K.*'
http:/\example.com

Or, if you want to read all headers, content and the --write-out variables line (according to your script):

response=$(curl -H 'Cache-Control: no-cache' -s -i -k --max-time 2 --write-out '%{http_code} %{size_header} %{redirect_url} ' "$url")

# break the response in parts
headers=$(sed -n '1,/^\r$/p' <<<"$response")
content=$(sed -e '1,/^\r$/d' -e '$d' <<<"$response")
read -r http_code size_header redirect_url < <(tail -n1 <<<"$response")

# get the real Location
location=$(grep -oP 'Location: \K.*' <<<"$headers")

Fully integrated in your script, this looks like:

#!/bin/bash
# Usage: urls-checker.sh domains.txt
file="$1"
while read -r url; do
    # read the response to a variable
    response=$(curl -H 'Cache-Control: no-cache' -s -i -k --max-time 2 --write-out '%{http_code} %{size_header} %{redirect_url} ' "$url")

    # break the response in parts
    headers=$(sed -n '1,/^\r$/p' <<<"$response")
    content=$(sed -e '1,/^\r$/d' -e '$d' <<<"$response")
    read -r http_code size_header redirect_url < <(tail -n1 <<<"$response")

    # get the real Location
    location=$(grep -oP 'Location: \K.*' <<<"$headers")

    # get the title
    title=$(sed -n 's/.*<title>\(.*\)<\/title>.*/\1/ip;T;q'<<<"$content")

    printf "***Url: %s\n\n" "$url"
    printf "Status: %s\n\n" "$http_code"
    printf "Size: %s\n\n" "$size_header"
    printf "Redirect-url: %s\n\n" "$location"
    printf "Title: %s\n\n" "$title"
    printf "Body: %s\n\n" "$(head -c 100 <<<"$content")"
done < "$file"
like image 122
randomir Avatar answered Nov 14 '22 22:11

randomir


According to @randomir answer and since I was only need raw redirect URL I use this command on my batch

 curl  -w "%{redirect_url}" -o /dev/null -s "https://stackoverflow.com/q/46507336/3019002"
like image 34
Salem Avatar answered Nov 14 '22 21:11

Salem