Skip to content

Instantly share code, notes, and snippets.

@MircoBabin
Created October 21, 2020 08:16
Show Gist options
  • Save MircoBabin/92399f7faa0bb456a87455bbe4d6a028 to your computer and use it in GitHub Desktop.
Save MircoBabin/92399f7faa0bb456a87455bbe4d6a028 to your computer and use it in GitHub Desktop.
Convert IIS web.config to Apache .htaccess
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>IIS web.config to Apache .htaccess rule translator</title>
<style>
#xmldoc {
width: 100%;
height: 200px;
}
#result {
font-family: consolas;
font-size: 11px;
color:#444;
background:#f9f9f9;
border:1px solid #f1f1f1;
padding: 5px;
}
</style>
<script>
function convertRule(rule) {
//<rule name="..." stopProcessing="true">
var name = rule.getAttribute("name");
var stopProcessing = (rule.getAttribute("stopProcessing") === "true");
//<match url="...">
var match = rule.getElementsByTagName("match");
if (match.length != 1) {
console.log("Rule has multiple <match> elements", rule);
return false;
}
match = match[0];
var matchurl = match.getAttribute("url");
if (matchurl === null || matchurl === "") {
console.log("Rule has no <match url=\"...\"> attribute", rule);
return false;
}
//<conditions>
var conditions = rule.getElementsByTagName("conditions");
if (conditions.length>0) {
console.log("Rule has <conditions>, conditions conversion is not supported", rule);
return false;
}
//<action type="Rewrite" url="..." />
var action = rule.getElementsByTagName("action");
if (action.length != 1) {
console.log("Rule has multiple <action> elements", rule);
return false;
}
action = action[0];
var actiontype = action.getAttribute("type");
if (actiontype !== "Rewrite") {
console.log("Rule action is not Rewrite - <action type=\"Rewrite\">", rule);
return false;
}
var actionurl = action.getAttribute("url");
if (matchurl === null || matchurl === "") {
console.log("Rule has no <action url=\"...\"> attribute", rule);
return false;
}
var appendQueryString = (action.getAttribute("appendQueryString") === "true");
//
//.htaccess
//
var RewriteRedirect = false;
//.htacces output url
var RewriteOutputUrl = actionurl;
if (RewriteOutputUrl == "/-") {
RewriteOutputUrl = "-";
RewriteRedirect = "404";
} else {
//strip starting // from "//index.php..."
if (RewriteOutputUrl.substring(0,2) == "//") {
RewriteOutputUrl = RewriteOutputUrl.substring(2);
}
//replace {R:1} with $1
var regex = /{R:(\d{1})}/;
while(regex.test(RewriteOutputUrl)) {
RewriteOutputUrl = RewriteOutputUrl.replace(regex, '$$' + RegExp.$1 );
}
}
//Build RewriteRule
var RewriteRule = "#web.config rule " + name + "\r\n";
RewriteRule += "RewriteRule " + matchurl + " " + RewriteOutputUrl;
if (stopProcessing || appendQueryString || RewriteRedirect !== false) {
RewriteRule += " [";
if (stopProcessing) RewriteRule += "L,";
if (RewriteRedirect !== false) RewriteRule += "R=" + RewriteRedirect + ",";
if (appendQueryString) RewriteRule += "QSA,";
RewriteRule = RewriteRule.slice(0,-1) + "]";
}
RewriteRule += "\r\n\r\n";
// Output
return RewriteRule;
}
function convert() {
var xml = document.getElementById("xmldoc").value.trim();
var result = document.getElementById("result");
result.innerHTML = "";
if (xml.length == 0) {
alert("XML is empty");
return;
}
const parser = new DOMParser;
var xmldoc = parser.parseFromString(xml, "application/xml");
if (xmldoc.getElementsByTagName("parsererror").length > 0) {
console.log(xmldoc);
alert("Invalid XML, see console");
return;
}
var rules = xmldoc.getElementsByTagName("rule");
var converted = 0;
var unconverted = 0;
for (var i=0; i < rules.length; i++) {
var rule = rules[i];
var htaccess = convertRule(rules[i]);
if (converted !== false) {
converted++;
result.innerHTML += htaccess;
} else {
unconverted++;
}
}
alert('Rules: ' + rules.length + "\n" +
'Converted: ' + converted + "\n" +
(unconverted>0 ? 'Unconverted: ' + unconverted + ", see console\n" : '')
);
}
</script>
</head>
<body>
<h1>Paste web.config</h1>
<textarea id="xmldoc"></textarea>
<button onclick="convert()">Convert to .htaccess</button>
<h1>Generated .htacess</h1>
<pre id="result"></pre>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment