I'd like to allow all origins to fetch resources from my apache server.
Instead of adding:
Access-Control-Allow-Origin: *
I would like my server to craft a special response with :
Access-Control-Allow-Origin: <the value of the Origin received in the request>
Is there something I can add to httpd.conf to achieve this ?
Seems it can be achieved by adding those two lines:
SetEnvIf Origin ".*\S.*" ORIGIN=$0
Header always set Access-Control-Allow-Origin %{ORIGIN}e env=ORIGIN
The regex pretty much means anything except newline, tab, and space, so as long as the Origin is not empty add it to the response header.
I am running my apache on http://localhost:8083 and i am calling an API hosted on local box i.e. http://localhost:8082
I want to map http://localhost:8083/test-call/abc/authorize call to actual service call i.e. http://localhost:8082/TestCall/abc/authorize.
I have rewrite engine as follows in httpd.conf file:
RewriteEngine on
RewriteRule "^/test-call/(.*)$" "http://localhost:8082/TestCall/$1"
I can see that the call is being mapped correctly from developer console of chrome i.e. http://localhost:8082/TestCall/abc/authorize and i have disabled CORS on my browser as i am testing the API call only.
I have added the following headers in my httpd.conf file:
Header set Access-Control-Allow-Origin "http://localhost:8083"
Header always set Access-Control-Allow-Headers "Authorization, X-Requested-With, Content-Type, content-type, x-requested-with, Accept, Access-Control-Allow-Origin, Cache-Control"
Header always set Cache-Control "no-cache, no-store, must-revalidate"
Header always set Access-Control-Allow-Methods "GET, POST, DELETE, HEAD, OPTIONS"
Header always set Access-Control-Expose-Headers "Content-Security-Policy, Location"
Header always set Access-Control-Max-Age "3600"
Header always set REMOTE_USER "abc.def#db.com"
It's a react application and the bundles are getting loaded correctly with the specified headers above and also the REMOTE_USER is getting added to the REPONSE_HEADERS but for the rewritten URL, the headers are not getting applied.
I want to pass the REMOTE_USER header in the API call after rewrite/redirect.
I have enabled mod_headers and mod_rewrite.
What am i missing?
In my local machine when I try to send a request via ajax using cross domain the request doesn't complete. I added this options to my .htaccess file:
Header always set Access-Control-Allow-Origin "https://accepted-domain"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
Header always set Access-Control-Max-Age "1000"
Header always set Access-Control-Allow-Headers "x-requested-with, Content-Type, origin, authorization, accept, client-security-token"
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]
After that, everything worked just fine but when I uploaded this to my cPanel server the request didn't complete.
However, if I remove these lines from the .htaccess file everything works just fine.
The question is: How to disable this Access-Control-Allow-Origin in my cPanel host to define it with the domain I want to accept only ?
UPDATED
When I sent the request on my cPanel hosting the response was this message:
Failed to load http://receiver-domain.com/create.php: The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed. Origin 'http://sender-domain.com' is therefore not allowed access.
Which means the Access-Control-Allow-Origin has been set somewhere else.
I am trying to enable CORS on my server. It hosts both an Apache HTTPD and an Apache Tomee.
HTTPD is configured as:
SetEnvIf Origin "^https://(.+\.)?my-domain.com$" allowed_origin=$0
Header always set Access-Control-Allow-Origin %{allowed_origin}e env=allowed_origin
Header set Access-Control-Allow-Credentials "true"
Header set Access-Control-Allow-Methods "GET, POST, OPTIONS, HEAD, PUT, DELETE, PATCH"
Header set Access-Control-Allow-Headers "accept,x-requested-method,origin,x-requested-with,x-request,cache-control,content-type"
Header set Access-Control-Max-Age "600"
and my Tomee web XML :
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>Origin,Accept,X-Requested-With,Content-Type,Access-Control-Request-Method,Access-Control-Request-Headers,Accept-Language,Keep-Alive</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.methods</param-name>
<param-value>GET,POST,HEAD,OPTIONS,PUT,PATCH,DELETE</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
My problem is I get the Access-Control-Allow-Credentials header twice in the response to the preflight OPTIONS request :
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://my-origin.my-domain.com
Access-Control-Allow-Origin: https://my-origin.my-domain.com
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 600
Access-Control-Allow-Methods: GET, POST, OPTIONS, HEAD, PUT, DELETE, PATCH
Access-Control-Allow-Headers: accept,x-requested-method,origin,x-requested-with,x-request,cache-control,content-type,authorization
I don't understand why the usage of the set keyword in my HTTPD configuration does not remove the duplicate Access-Control-Allow-Origin.
Moreover, if I remove the 'always' keyword it returns one Access-Control-Allow-Origin only...
Experiencing a similar issue. Spent a lot of time in debugging.
It is a bug in Apache. A failure of the internal design and a failure to document it.
Header [table] set [cookie] [value] [...]
That's the command to manipulate headers. There are at least two cookie tables in apache.
onsuccess, default, used for 20X status codes.
always, used for errors, including redirects codes.
Judging by my experience in the wild, all cookies from all tables are appended to the response.
In your example, the cookie set by Tomcat is in the onsuccess table, the cookie sets in apache is in the always table. The response gets both cookies, hence the duplication.
It gets more messy than that. The tables have different meaning depending on what modules are in use. For instance, when using proxy or CGI, the relevant table for cookies is onsuccess if the upstream server delivers an error successfully, but always if an internal apache error occurs.
This behavior is not documented. That seems not intentional but a consequence of apache internals. In the current state, it is basically impossible to manipulate headers properly with Apache.
The accepted answer is correct. This is just a way of handling it that I've been using.
SetEnvIf Origin "^(.*(\.yoursite.com)[:0-9]*)$" cors=$1
# wash out these headers in the 'onsuccess' table if we get them from the backend
Header onsuccess unset Access-Control-Allow-Origin env=cors
Header onsuccess unset Access-Control-Allow-Credentials env=cors
Header onsuccess unset Access-Control-Allow-Methods env=cors
Header onsuccess unset Access-Control-Allow-Headers env=cors
# add them to the 'always' table
Header always set Access-Control-Allow-Origin %{cors}e env=cors
Header always set Access-Control-Allow-Credentials "true" env=cors
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, PUT, DELETE" env=cors
Header always set Access-Control-Allow-Headers "accept,x-requested-method,origin" env=cors
Is there a way to set a new response header conditionally, where the condition uses another response header? Specifically, the new response header should be set only if the response has a certain Content-Type.
I have looked into mod_headers in combination with mod_setenvif but it looks like conditions can only use request headers, not response headers.
Thanks, John
Apache 2.4 is the answer:
Set Cache-Control header when response content type is application/pdf
Header set Cache-Control "no-store,no-transform" "expr=%{resp:Content-Type} =~ m|application/pdf|"
Do NOT try with the IF directive. It is evaluated too early in the process. For example, the following will NOT work:
<If "%{resp:Content-Type} =~ m|application/pdf|">
Header set Cache-Control "no-store, no-transform"
</If>