{"id":116,"date":"2009-10-27T13:09:14","date_gmt":"2009-10-27T17:09:14","guid":{"rendered":"http:\/\/www.braindeadprojects.com\/blog\/?p=116"},"modified":"2009-10-27T13:34:29","modified_gmt":"2009-10-27T17:34:29","slug":"directoryslash-hacking","status":"publish","type":"post","link":"http:\/\/www.braindeadprojects.com\/blog\/what\/directoryslash-hacking\/","title":{"rendered":"DirectorySlash Hacking"},"content":{"rendered":"<p>The other day I came across the following scenario: A customer wanted to use Apache proxying to hide the virtual hostname that his customers were really pulling content from. The rewrite rule on the &#8220;masking host&#8221; (which I refer to as www.proxy.net in these examples) is easy enough:<\/p>\n<blockquote><p>RewriteRule ^\/~(.*)$ http:\/\/user.proxiedto.net\/~$1 [P]<\/p><\/blockquote>\n<p>Which works pretty well:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-117\" title=\"How the mod_rewrite [P] works.\" src=\"http:\/\/www.braindeadprojects.com\/blog\/wp-content\/apache-proxy-2.png\" alt=\"How the mod_rewrite [P] works.\" width=\"415\" height=\"282\" srcset=\"http:\/\/www.braindeadprojects.com\/blog\/wp-content\/apache-proxy-2.png 415w, http:\/\/www.braindeadprojects.com\/blog\/wp-content\/apache-proxy-2-300x203.png 300w\" sizes=\"(max-width: 415px) 100vw, 415px\" \/><\/p>\n<p>The problem is what happens when DirectorySlash is enabled on the proxied-to host\u00a0 (which it is by default). DirectorySlash fixes incorrectly identified resources &#8211; as an example, if you request a directory but <strong><em>without <\/em><\/strong>the trailing forwardslash.<\/p>\n<blockquote><p>GET <strong>\/~gillespiem\/images <\/strong>HTTP\/1.1<br \/>\nHost: www.proxy.net<br \/>\n&#8230;<\/p><\/blockquote>\n<p>In this instance, you get a 301 redirect that appends a &#8220;\/&#8221; to the end of the request BUT also sets the Location header to\u00a0 the <em><strong>proxied-to<\/strong><\/em> virtualhostname.\u00a0 The Jig is up &#8211; and now the address bar in the browser indicates the <strong><em>real <\/em><\/strong>host the end-user is speaking to<strong> <\/strong>:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-118\" title=\"When mod_rewrite [P] and DirectorySlash collide.\" src=\"http:\/\/www.braindeadprojects.com\/blog\/wp-content\/apache-proxy-3.png\" alt=\"When mod_rewrite [P] and DirectorySlash collide.\" width=\"415\" height=\"282\" srcset=\"http:\/\/www.braindeadprojects.com\/blog\/wp-content\/apache-proxy-3.png 415w, http:\/\/www.braindeadprojects.com\/blog\/wp-content\/apache-proxy-3-300x203.png 300w\" sizes=\"(max-width: 415px) 100vw, 415px\" \/><\/p>\n<p>Here&#8217;s a snippet of response from the site:<\/p>\n<blockquote><p>HTTP\/1.1 301 Moved Permanently<br \/>\nDate: Tue, 27 Oct 2009 16:28:27 GMT<br \/>\nServer: Apache\/2.2.3 (CentOS)<br \/>\nLocation: <strong>http:\/\/user.proxiedto.net\/~gillespiem\/images\/<\/strong><br \/>\n&#8230;<\/p><\/blockquote>\n<p>I&#8217;ve not been able to find an easy way to change what DirectorySlash uses in the Location header (maybe you can&#8217;t). DirectorySlash is important, so simply not using it won&#8217;t work in this application. Instead, I opted to use a RewriteMap to simply write my own version:\u00a0 <a title=\"DirectorySlashHack\" href=\"http:\/\/braindeadprojects.com\/src\/directoryslashhack\">DirectorySlashHack<\/a> and enable it in the vhost container (on the proxy-to site) ala:<\/p>\n<blockquote><p>DirectorySlash off<br \/>\nRewriteMap directoryslashhack\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 prg:\/etc\/httpd\/maps\/directoryslashhack<br \/>\nRewriteRule ^\/~([^\/]+)(\/?.*)\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ${directoryslashhack:%1*$1*$2}<\/p><\/blockquote>\n<p>While the solution is hack-ish (and the script and rewriterule could use a small bit of cleanup), it seems to work so far. The perl script determines if the requested resource is a directory, and if so it issues the appropriate 301 redirect using a customizable location header (which allows me to force the cleaned-up request back to the proxy).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The other day I came across the following scenario: A customer wanted to use Apache proxying to hide the virtual hostname that his customers were really pulling content from. The rewrite rule on the &#8220;masking host&#8221; (which I refer to as www.proxy.net in these examples) is easy enough: RewriteRule ^\/~(.*)$ http:\/\/user.proxiedto.net\/~$1 [P] Which works pretty &hellip; <a href=\"http:\/\/www.braindeadprojects.com\/blog\/what\/directoryslash-hacking\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">DirectorySlash Hacking<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-116","post","type-post","status-publish","format-standard","hentry","category-what"],"_links":{"self":[{"href":"http:\/\/www.braindeadprojects.com\/blog\/wp-json\/wp\/v2\/posts\/116"}],"collection":[{"href":"http:\/\/www.braindeadprojects.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.braindeadprojects.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.braindeadprojects.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.braindeadprojects.com\/blog\/wp-json\/wp\/v2\/comments?post=116"}],"version-history":[{"count":21,"href":"http:\/\/www.braindeadprojects.com\/blog\/wp-json\/wp\/v2\/posts\/116\/revisions"}],"predecessor-version":[{"id":139,"href":"http:\/\/www.braindeadprojects.com\/blog\/wp-json\/wp\/v2\/posts\/116\/revisions\/139"}],"wp:attachment":[{"href":"http:\/\/www.braindeadprojects.com\/blog\/wp-json\/wp\/v2\/media?parent=116"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.braindeadprojects.com\/blog\/wp-json\/wp\/v2\/categories?post=116"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.braindeadprojects.com\/blog\/wp-json\/wp\/v2\/tags?post=116"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}