Skip to content

Instantly share code, notes, and snippets.

@Mte90
Last active February 24, 2021 14:51
Show Gist options
  • Save Mte90/c6568811cd38b60cf05f0e9d8f16bc7a to your computer and use it in GitHub Desktop.
Save Mte90/c6568811cd38b60cf05f0e9d8f16bc7a to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
#
# This script injects a file into the current Apache2 environment temporarily
# in order to check its syntax.
#
# INSTALL:
# sed -i "2i ServerName example.com" /etc/apache2/sites-available/000-default.conf
# Require adding this line to the example conf
#
# USAGE:
# validate-htaccess <file|stdin> [-u example.com]
#
# EXAMPLE:
# validate-htaccess [/path/to/.htaccess][stdin] [-u (domain from apache setting)]
#
# EXIT CODES:
#
# 0 - The syntax is valid.
# 1 - The syntax is invalid, see STDERR for details.
# 2 - The httpd binary could not be found.
# 3 - No parameters are used.
#
# Author: Liquid Web & Daniele Scasciafratte
# License: MIT
# If parameter is used or stdin
if [ "$#" == 0 ]; then
file=$(mktemp)
sleep 1
if read -r -t 0; then
cat > tee "$file"
else
echo "No parameters or stdin, closed."
exit 3
fi
else
file=${1:?No configuration file specified.}
fi
APACHE_DOMAIN="example.com"
while getopts u: option
do
case "${option}"
in
u) APACHE_DOMAIN=${OPTARG};;
*) echo '';;
esac
done
# Ensure the file can be loaded.
tmpfile=$(mktemp)
cat "$file" > "$tmpfile"
sed --in-place '/RewriteBase/d' "$tmpfile"
# Ensure that httpd is available.
if [[ ! $(command -v httpd) && ! $(command -v apache2ctl) ]]; then
echo 'Unable to find the httpd binary or apache2ctl script, is Apache2 installed?' 1>&2
exit 2
fi
command -v httpd &> /dev/null
exit_code=$?
if [ $exit_code -eq 0 ]; then
httpd="httpd"
fi;
command -v apache2ctl &> /dev/null
exit_code=$?
if [ $exit_code -eq 0 ]; then
httpd="apache2ctl"
fi;
# Get the name of the current configuration file.
current_config=$(${httpd} -V \
| grep -E -o -e 'SERVER_CONFIG_FILE="(.+)"' \
| sed 's/SERVER_CONFIG_FILE=//; s/"//g')
# Now, use Apache to validate itself, injecting $FILE into the current
# server environment.
results=$(${httpd} -t -C "Include ${current_config}" -f "$tmpfile" -C "ServerName ${APACHE_DOMAIN}" 2>&1)
exit_code=$?
# Remove the temp file.
rm "$tmpfile"
# If the check passed, there's nothing more to do.
if [ $exit_code -eq 0 ]; then
exit
fi
# Something went wrong, so we need to parse the results.
tmpfilename=${tmpfile##*/}
echo "$results" | sed -E 's/^.+'"$tmpfilename"': //' 1>&2
exit 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment