-
-
Save wallentx/3f49089fa32e084e29085f5208c6dead to your computer and use it in GitHub Desktop.
GNU URL
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Initialize options | |
follow_redirects=false | |
show_headers_only=false | |
silence_output=false | |
# Process options | |
while getopts "LsI" opt; do | |
case $opt in | |
L) | |
follow_redirects=true | |
;; | |
s) | |
silence_output=true | |
;; | |
I) | |
show_headers_only=true | |
;; | |
\?) | |
echo "Invalid option: -$OPTARG" >&2 | |
exit 1 | |
;; | |
esac | |
done | |
# Shift off the options and flags processed by getopts | |
shift $((OPTIND-1)) | |
# Initial URL | |
url_input=$1 | |
follow_redirect() { | |
local url="$1" | |
# Remove protocol part | |
local stripped_url="${url#http://}" | |
stripped_url="${stripped_url#https://}" | |
# Extract host and path | |
local host="${stripped_url%%/*}" | |
local path="${stripped_url#"$host"}" | |
path="${path:-/}" # Default path to '/' if empty | |
# Determine protocol and port | |
local protocol port | |
if [[ "$url" == https://* ]]; then | |
protocol="openssl s_client -quiet -ignore_unexpected_eof -connect" | |
port="443" | |
else | |
protocol="/dev/tcp" | |
port="80" | |
fi | |
# Make the request and capture the response | |
if [ "$protocol" == "/dev/tcp" ]; then | |
exec 3<>/dev/tcp/${host}/${port} | |
echo -e "GET ${path} HTTP/1.1\r\nHost: ${host}\r\nConnection: close\r\n\r\n" >&3 | |
response=$(cat <&3) | |
else | |
response=$(echo -e "GET ${path} HTTP/1.1\r\nHost: ${host}\r\nConnection: close\r\n\r\n" | openssl s_client -quiet -ignore_unexpected_eof -connect "${host}:${port}" 2>/dev/null) | |
fi | |
# Parse status code and Location header | |
local status=$(echo "$response" | grep -oE "HTTP/1.1 [0-9]+" | awk '{print $2}') | |
local location=$(echo "$response" | grep -i "^Location:" | head -n 1 | cut -d' ' -f2) | |
# Strip carriage return from the location | |
location=$(echo "$location" | tr -d '\r') | |
if $silence_output && ! $show_headers_only; then | |
if [[ "$status" != "301" && "$status" != "302" ]]; then | |
echo "$response" | tr -d '\r' | sed -n '/^$/,$p' # Print response body only | |
fi | |
else | |
if $show_headers_only; then | |
echo "$response" | grep -P "^(HTTP/1.1|[A-Za-z-]+:)" | |
elif [[ "$status" == "301" || "$status" == "302" ]] && [ ! -z "$location" ]; then | |
echo "Following redirect to $location" >&2 | |
follow_redirect "$location" | |
else | |
echo "$response" | |
fi | |
fi | |
} | |
follow_redirect "$url_input" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment