I'm attempting to configure Apache to do something like a proxy to some remote server, to permit mix-domain AJAX using CORS. To do this, I want Apache to reply to 2 HTTP verbs, like so:

  1. OPTIONS: React to this CORS 'pre-flight' request with a few simple HTTP headers. I'd in your mind that this may be an easy CGI script (options.pl).

  2. Publish: Proxy all Publish demands towards the remote server, but add the Access-Control-Allow-Origin "*" header to permit the mix-domain request to occur.

I'm able to achieve these two needs individually, however i cannot configure Apache to complete both. However , once the ProxyPass and ProxyPassReverse is set up, the choices demands no more hit the CGI script, they're proxied towards the remote server.

My current config is below. Let me solve this having a pure web-server solution e.g. Apache/Nginx (instead of running some application code), if at all possible.

<VirtualHost *:80>

    ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/

    DocumentRoot /var/www

    <Location "/">

        # Disallow all verbs except OPTIONS and POST
        order deny,allow
        deny from all

        # OPTIONS should be handled by a local CGI script
        <Limit OPTIONS>
            allow from all
            Script OPTIONS /cgi-bin/options.pl
        </Limit>

        # POST requests are proxied to a remote server
        <Limit POST>
            allow from all
            ProxyPass http://somewhere-else/
            ProxyPassReverse http://somewhere-else/
            Header add Access-Control-Allow-Origin "*"
        </Limit>

    </Location>
</VirtualHost>

Here's how I have solved it using Nginx. Note that i'm while using Headers More module which needed me to compile Nginx from source.

location / {

    if ($request_method = 'OPTIONS') {
        more_set_headers 'Access-Control-Allow-Origin: *';
        more_set_headers 'Access-Control-Allow-Methods: POST, OPTIONS';
        more_set_headers 'Access-Control-Max-Age: 1728000';
        more_set_headers 'Content-Type: text/plain; charset=UTF-8';

        return 200;
    }

    if ($request_method = 'POST') {
        more_set_headers 'Access-Control-Allow-Origin: *';
        proxy_pass http://somewhere-else;
    }
}

You should use my nginx_mix_origin_module now. It props up full CORS feature: https://github.com/yaoweibin/nginx_cross_origin_module

Example:

http {

    cors on;
    cors_max_age     3600;
    cors_origin_list unbounded;
    cors_method_list GET HEAD PUT POST;
    cors_header_list unbounded;

    server {
        listen       80;
        server_name  localhost;

        location / {
            root   html;
            index  index.html index.htm;
        }
    }
}