title: How can I configure Apache to reject all requests except an XMLHttpRequest from localhost?
body: <p>I have a Flask website, served with mod_wsgi (3.4) and Apache (2.4.7) on Ubuntu 14.04. The virtual host config has two directory blocks – one for the Flask app, and one for a directory of static files, which the Flask app sometimes fetches via an <code>XMLHttpRequest</code>.</p>
  
  <p>I'd like the directory of static files to be accessible only to requests from the Flask app, but am having trouble setting Apache up to do this. I've tried <code>Require local</code>, <code>Require ip 127.0.0.1</code> and <code>Require sd.d.com</code> but each of these causes a 403 for the <code>XMLHttpRequest</code>.</p>
  
  <p>[The <code>XMLHttpRequest</code> works fine with <code>Require all granted</code> (and the Flask app and static directory are on the same subdomain, server and port), so I don't think it's a CORS-related issue.]</p>
  
  <p>Here's my Apache conf file:</p>
  
  <pre><code>&lt;VirtualHost *:80&gt;
    ServerName sd.d.com
    WSGIDaemonProcess mag user=www-data group=www-data threads=5 python-path=/var/www/sd.d.com:/var/www/sd.d.com/venv/lib/python3.4/site-packages
    WSGIProcessGroup mag
    WSGIScriptAlias / /var/www/sd.d.com/mag.wsgi
    &lt;Directory /var/www/sd.d.com&gt;
      Require all granted
    &lt;/Directory&gt;
    Alias /models /var/www/sd.d.com/models
    &lt;Directory /var/www/sd.d.com/models&gt;
      Require local # Tried this
      # Require ip 127.0.0.1 # Also tried this
      # Require host sd.d.com # Also tried this
    &lt;/Directory&gt;
    ErrorLog /var/www/sd.d.com/error.log
    CustomLog /var/www/sd.d.com/access.log combined
    LogLevel debug
  &lt;/VirtualHost&gt;
  </code></pre>
  
  <p>Here's a sample from my access.log after a 403:</p>
  
  <pre><code>02dec1b9.bb.sky.com - - [27/Apr/2016:19:02:49 +0000] "GET /models/cbc96411-aa47-4417-bea4-95943b98b1d3/cbc96411-aa47-4417-bea4-95943b98b1d3.stl HTTP/1.1" 403 581 "http://sd.d.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.86 Safari/537.36"
  </code></pre>
  
  <p>Don't know if this is related, but I was expecting the <code>XMLHttpRequest</code> request to come from localhost rather than 02dec1b9.bb.sky.com. My access log file is set up as below:</p>
  
  <pre><code>LogFormat "%v:%p %h %l %u %t \"%r\" %&gt;s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
  LogFormat "%h %l %u %t \"%r\" %&gt;s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
  LogFormat "%h %l %u %t \"%r\" %&gt;s %O" common
  LogFormat "%{Referer}i -&gt; %U" referer
  LogFormat "%{User-agent}i" agent
  </code></pre>
  
  <p>The same failed request from my error.log:</p>
  
  <pre><code>[Wed Apr 27 19:02:49.381706 2016] [authz_core:error] [pid 18700:tid 140508152153856] [client 2.222.193.185:59865] AH01630: client denied by server configuration: /var/www/sd.d.com/models/cbc96411-aa47-4417-bea4-95943b98b1d3/cbc96411-aa47-4417-bea4-95943b98b1d3.stl, referer: http://sd.d.com/
  </code></pre>
  
  <p>How can I configure Apache to reject all requests except the desired <code>XMLHttpRequest</code>?</p>
  
  <p><strong>Update</strong></p>
  
  <p>If I set the models/ directory to <code>Require all granted</code> the successful <code>XMLHttpRequest</code> is logged as 2.222.193.185 rather than 02dec1b9.bb.sky.com:</p>
  
  <pre><code>2.222.193.185 - - [28/Apr/2016:09:41:02 +0000] "GET /models/ca19d6ca-715e-4a0f-89f0-f5e3059f57ff/ca19d6ca-715e-4a0f-89f0-f5e3059f57ff.stl HTTP/1.1" 200 4426280 "http://sd.d.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.86 Safari/537.36"
  </code></pre>