Created
March 29, 2020 02:02
-
-
Save inkblot/507c58c70cca4f9358185ec895a62b5c to your computer and use it in GitHub Desktop.
Parse a URL in bash without forking
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 | |
_SELF="${0##*/}" | |
_HERE="$(dirname $(realpath ${0}))" | |
function parse_url() { | |
local url _url __url proto uphp user_pass host_port user pass host port path query_string | |
url="${1}" | |
proto="${url%://*}" # proto: everything up to the first '://' | |
# There should definitely be a proto, neither empty nor equal to url | |
if [ "${proto}" == "" -o "${proto}" == "$url" ]; then | |
echo "Invalid url: ${url}" >&2 | |
return 1 | |
fi | |
_url="${url:$((3 + ${#proto}))}" # _url: url minus "${proto}://" | |
uphp="${_url%%/*}" # uphp (User-Password-Host-Port): everything up to the first '/' in _url | |
__url="${_url:$((${#uphp} + 1))}" # __url: _url minus uphp | |
user_pass="${uphp%%@*}" | |
if [ "${user_pass}" == "${uphp}" ]; then | |
user_pass="" | |
host_port="${uphp}" | |
else | |
host_port="${uphp#*@}" | |
fi | |
user="${user_pass%%:*}" # user: everything up to the first ':' in user_pass | |
if [ "${user}" == "${user_pass}" ]; then | |
pass="" | |
else | |
pass="${user_pass#*:}" # pass: everything after the first ':' in user_pass, but only if there was a ':' | |
fi | |
host="${host_port%%:*}" # host: everything up to the first ':' in host_port | |
if [ "${host}" == "${host_port}" ]; then | |
port="80" | |
else | |
port="${host_port#*:}" # port: everything after the first ':' in host_port, but only if there was a ':' | |
fi | |
path="${__url%%\?*}" # path: everything up to the first '?' in __url | |
if [ "${path}" == "${__url}" ]; then | |
query_string="" | |
else | |
query_string="${__url%*\?}" # query_string: everything after the first '?' in __url, but only if there was a '?' | |
fi | |
echo "{"\ | |
"\"proto\": \"${proto}\","\ | |
"\"host\": \"${host}\","\ | |
"\"port\": ${port},"\ | |
"\"username\": \"${user}\","\ | |
"\"password\": \"${pass}\","\ | |
"\"path\": \"${path}\","\ | |
"\"query_string\": \"${query_string}\""\ | |
"}" | |
} | |
if [ "${_SELF}" = "parse-url.sh" ]; then | |
set -eu | |
parse_url "$@" | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment