Let Apache serve multiple directories through single <Location>
-
21-08-2019 - |
Question
I have an issue with serving a large amount of VirtualHosts and I was wondering if there is a more efficient way of doing things.
I'm currently using the Location directive to serve a large amount projects from different departments, over 300 projects from 19 departments in total. The structures is the same for every Location directive except for the directories the files are served from. What I currently have is a large file that looks something like this:
<VirtualHost *>
ServerName www.myserver.com
<Location /departmentA/project1>
AuthType Basic
AuthName "By Invitation Only"
AuthUserFile /usr/local/departmentA/project1/passwords
Require valid-user
</Location>
<Location /departmentA/project2>
AuthType Basic
AuthName "By Invitation Only"
AuthUserFile /usr/local/departmentA/project2/passwords
Require valid-user
</Location>
<Location /departmentB/project1>
AuthType Basic
AuthName "By Invitation Only"
AuthUserFile /usr/local/departmentA/project1/passwords
Require valid-user
</Location>
</VirtualHost>
As you can see all these structures are the same except for the paths. What I would like is of course something where I can use variables for the department and project names and just maintain a single Location directive. I assume that this is also less heavy on the server and memory.
<VirtualHost *>
ServerName www.myserver.com
<Location /$1/$2>
AuthType Basic
AuthName "By Invitation Only"
AuthUserFile /usr/local/$1/$2/passwords
Require valid-user
</Location>
</VirtualHost>
Solution
I don't know of any way to do that specifically, as I don't think AuthUserFile
accepts a dynamic argument. It might be easiest to write a little script in your language of choice that takes a template for the <Location>
block and repeats it for each directory you want to protect. Example, in Python:
#!/usr/bin/python
import sys
print '<VirtualHost *:80>'
print ' ServerName www.myserver.com'
for path in sys.stdin:
print ' <Location /%s>' % path.strip()
print ' AuthType Basic'
print ' AuthName "By Invitation Only"'
print ' AuthUserFile /usr/local/%s/passwords' % path.strip()
print ' Require valid-user'
print ' </Location>'
print '</VirtualHost>'
For each line of the form 'departmentA/project1' it reads on standard input, it prints out the corresponding <Location>
section.
OTHER TIPS
Have you tried the <LocationMatch> directive?
It takes a regular expression instead of a path. Depending on your paths and their associated sub-options, you may be able to reduce the hundreds of directives down to a more manageable handful of them.