User Tools

Site Tools


htaccess_recipes

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
Next revisionBoth sides next revision
htaccess_recipes [2021/04/05 07:17] – [Redirect to a custom error page] hc9htaccess_recipes [2022/02/23 21:41] – Added not about not applicable to nginx-served peteyboy
Line 1: Line 1:
 ====== .htaccess recipes ====== ====== .htaccess recipes ======
 +
 +:!: Note: .htaccess only works at SDF on pages served by Apache, which at the time of this writing (2022/02/23) is only on the cluster. Meaning that .htaccess will not do anything if placed in folders served by [[metaarray|The MetaArray]] or VHOST
 +
 +
 +=== Introduction ===
  
 .htaccess is the default file used by the [[http://httpd.apache.org/|Apache HTTP server]] (and others) in order to allow dynamic configuration. It's a plain text file that uses the same syntax present in the main configuration files (e.g., httpd.conf). It can contain a subset of Apache directives. The size of this subset depends on wheter the directives can be overridden or not (and this is present in the server configuration). In the Apache documentation you can see if a directive can be placed in a .htaccess file by checking that in the Context: line appears .htaccess. For instance, it's possible for the [[http://httpd.apache.org/docs/2.2/mod/core.html#forcetype|ForceType]] directive, but it's not for the  [[http://httpd.apache.org/docs/2.2/mod/core.html#errorlog|ErrorLog]] directive. file. .htaccess is the default file used by the [[http://httpd.apache.org/|Apache HTTP server]] (and others) in order to allow dynamic configuration. It's a plain text file that uses the same syntax present in the main configuration files (e.g., httpd.conf). It can contain a subset of Apache directives. The size of this subset depends on wheter the directives can be overridden or not (and this is present in the server configuration). In the Apache documentation you can see if a directive can be placed in a .htaccess file by checking that in the Context: line appears .htaccess. For instance, it's possible for the [[http://httpd.apache.org/docs/2.2/mod/core.html#forcetype|ForceType]] directive, but it's not for the  [[http://httpd.apache.org/docs/2.2/mod/core.html#errorlog|ErrorLog]] directive. file.
Line 20: Line 25:
 ===== Redirect to a custom error page ===== ===== Redirect to a custom error page =====
  
-Do you want your visitors see your custom error pages when something goes wrong (e.g., a page not found error)? There's already a tutorial about it: http://sdf.org/index.cgi?tutorials/errorpage+Do you want your visitors see your custom error pages when something goes wrong (e.g., a page not found error)? There's already a tutorial about it: [[custom_error_pages_for_your_site|custom error pages for your site]]
  
 ===== Deny directory listing ===== ===== Deny directory listing =====
Line 28: Line 33:
 ''Options -Indexes'' ''Options -Indexes''
  
 +===== Save the current directory as an environment variable =====
 +
 +You might already be aware that the options in an htaccess file will affect all the files in subdirectories of the htaccess file location, unless overridden by htaccess files deeper into the path. But did you ever wish you could dynamically infer the location of your base htaccess file, for substitution into later directives? It turns out that Perl regexes (used in Apache's mod_rewrite) are flexible enough to do the trick.
 +
 +If you made your website accessible via tilde-style URLs (running ''mkhomepg -d'' at the shell), then requests to anything under http://sdf.org/~YOURUSERNAME will have a different setting for DOCUMENT_ROOT than requests to the same content at http://YOURUSERNAME.sdf.org (assuming that ~/html and ~/public_html are symlinks to the same folder). A single htaccess serving both types of URLs cannot blindly make relative path substitutions in a RewriteRule directive (or even well-intentioned absolute path substitutions based on your knowledge of the SDF filesystem). Instead, you can first pass the requested URL through a do-nothing RewriteRule (the //pattern// ''^.*$'' matches everything, and the //substitution// ''-'' leaves it unchanged), extracting the current directory into the environment variable ''CWD''. Then you can use the value of ''CWD'' in a subsequent RewriteRule that performs an actual substitution. Here is an example:
 +
 +<code>
 +RewriteEngine on
 +RewriteBase "/"
 +RewriteCond $0#%{REQUEST_URI} ([^#]*)#(.*)\1$
 +RewriteRule ^.*$ - [E=CWD:%2]
 +
 +RewriteCond %{HTTP_HOST} ^(www\.)?sdf\.org$
 +RewriteCond %{REQUEST_FILENAME} !-f
 +RewriteCond %{REQUEST_FILENAME} !-d
 +RewriteRule ^.*$ %{ENV:CWD}/custom404.html
 +</code>
 +
 +The # symbol serves as an arbitrary delimiter, ensuring that the second parenthesized group captures the working directory that's known to the server at the time of processing. Whether the working directory is an absolute pathname on the filesystem or an alias that will later be expanded by mod_userdir, the environment variable ''CWD'' will have a value compatible with the order in which Apache processes UserDir and RewriteRule directives.
 +
 +This example can be extended to perform different redirections depending on which virtual host handled the transaction (just create a new stanza with a different condition on %{HTTP_HOST}). In this way you can give your visitors the same experience whether they've bookmarked your site as http://YOURUSERNAME.sdf.org or http://sdf.org/~YOURUSERNAME, without having to duplicate your content in multiple folders.
 +
 +Because these RewriteRules impose additional processing demands on the server for each request, hacks like these should be a last resort. If the other workarounds mentioned in [[custom_error_pages_for_your_site|custom error pages for your site]] address your use case, they should be implemented instead.
 ===== Add (or force) MIME-type ===== ===== Add (or force) MIME-type =====
  
htaccess_recipes.txt · Last modified: 2022/08/01 20:35 by peteyboy