reverseProxy: how to change content in embedded JavaScript file - javascript

I use Apache HTTP 2.4 as a reverse proxy. My configuration works fine except one thing:
I would like to change a string content (url) in an embedded JavaScript file
This is my actual virtual host configuration:
<VirtualHost web.mydomain.com:80>
ServerName web.mydomain.com
ServerAlias web.mydomain.com
DocumentRoot "..."
...
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]
#Options -Indexes
#ProxyRequests On
#ProxyPreserveHost Off
# Web App
ProxyPass /hello http://middleware.mydomain.com:8082/hello-world-0.0.7
ProxyPassReverse /hello http://middleware.mydomain.com:8082/hello-world-0.0.7
AddOutputFilterByType SUBSTITUTE text/html
Substitute "s|hello-world-0.0.7|hello|ni"
</VirtualHost>
Could you please help me?

Usually, you should be able to configure the external URL in your application server, thereby eliminating the need to do the substitution in your Apache server. Such a configuration would be more efficient.
Did you validate in your browser that the returned Content-Type matches your filter? You indicate a Javascript file but filter for text/html. (e.g. Chrome: open Developer tools > navigate to the page > open Network tab > click on the resource that needs substitution > Look for the Content-Type header in the response headers). The Content-Type header should match your filter.
If it still does not work, it is likely that the application server returns gzipped content (check for Content-Encoding: gzip in the response headers). In that case, it makes sense that substitution won't work.
To work around that, add the following directive in your Apache configuration:
RequestHeader unset Accept-Encoding
Please note that this results in a performance penalty since more data needs to be sent across the network. I won't recommend this solution in a production environment since it applies to all requests for the current Virtual Host. If you only need to use substitution for a single file, I recommend wrapping the AddOutputFilterByType, Substitute and RequestHeader directives in a block, so that Apache only does the additional work for that file:
<Location "/hello/path/to/your/javascript/file.js">
RequestHeader unset Accept-Encoding
AddOutputFilterByType SUBSTITUTE text/html
Substitute "s|hello-world-0.0.7|hello|ni"
</Location>

Related

Keycloak Admin Console showing a blank page

I have configured a Keycloak server with Apache at the front acting as a reverse proxy. Keycloak is running on http mode only, all the SSL is being handled by Apache. I've configured the whole system according to the official Keycloak docs.
The problem I'm facing is, on accessing the Keycloak admin console from a machine other than localhost, the page is blank (except the navbar). On accessing from the machine on which it is hosted (localhost), it works fine, but on accessing from any other machine it just shows a blank page. The server also does not throw any error. I'm attaching an image of the blank admin page below.
(source: firefoxusercontent.com)
Another thing to note would be, other pages, like my account page, are working fine. The problem is only with the main admin page. Also, I've noticed that the admin page is an Angular app, so that may be relevant.
Relevant configs and settings I'm using.
Keycloak settings (CLI commands).
embed-server --server-config=standalone.xml
/subsystem=undertow/server=default-server/http-listener=default/:write-attribute(name=proxy-address-forwarding,value=true)
/socket-binding-group=standard-sockets/socket-binding=proxy-https/:add(port=443)
/subsystem=undertow/server=default-server/http-listener=default/:write-attribute(name=redirect-socket,value=proxy-https)
Apache config.
<VirtualHost *:80>
DocumentRoot /var/www/html
RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
Redirect permanent '/' https://%{HTTP_HOST}
</VirtualHost>
<VirtualHost *:443>
DocumentRoot /var/www/html
ProxyPreserveHost On
ProxyRequests Off
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
ProxyPass /auth http://127.0.0.1:8080/auth
ProxyPassReverse /auth http://127.0.0.1:8080/auth
SSLEngine on
SSLCertificateFile /etc/ssl/certs/oauth-server.crt
SSLCertificateKeyFile /etc/ssl/private/oauth-server.key
<FilesMatch "\.(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
<Directory /usr/lib/cgi-bin>
SSLOptions +StdEnvVars
</Directory>
</VirtualHost>

ERR_CONTENT_DECODING_FAILED for one file after Joomla update

After updating Joomla to 3.8.1 today most of the admin tabbing and navigation functions stopped working in Chrome, FireFox, Win Safari, and IE 11. media/jui/js/bootstrap.min.js was failing to load with ERR_CONTENT_DECODING_FAILED. It still works in MS Edge.
This is occurring on machines in multiple locations and over multiple ISPs.
Actions taken (none of which have resolved):
Deleted file from server and replaced with backed up copy from last week and re-issued chmod 0644
Verified that public $gzip = '0'; in configuration.php
Tested in MS Edge where the error did not occur
Used MS Edge to go to Joomla Global Configuration > Server Settings and set Gzip Page Compression to No. Had been Yes.
Found that in browsers where it was failing if JS file is accessed without the versioning query string the browser can load file without error.
Found in Safari, IE 11, and iPhone Chrome the JS file displays and appears to be gzipped or otherwise encoded. Screenshot:
Cleared browser cache in Chrome
Went to chrome://net-internals and clicked Flush Socket Pools and Close Idle Sockets
Cache settings checked and it has been set to off the whole time:
System - Page Cache module also disabled
In this case the client had failed to mention they had added Sucuri Firewall service and that was where they corrupted cached file was being delivered from. Cleared cache at Sucuri and file no longer throws ERR_CONTENT_DECODING_FAILED
I had the same situation. Gzip on 0 in configuration.php did not work. So I found out that get_magic_quotes_gpc was deprecated in
libraries\src\Application\AdministratorApplication.php.
In my case I solved it by editing the default htaccess that my Joomla 4.2.X came with.
You have to leave these lines activated.
Header always set Cross-Origin-Resource-Policy "same-origin".
Header always set Cross-Origin-Embedder-Policy "require-corp".
And you have to remove this code:
<IfModule mod_headers.c>
# Serve gzip compressed CSS files if they exist
# and the client accepts gzip.
RewriteCond "%{HTTP:Accept-encoding}" "gzip"
RewriteCond "%{REQUEST_FILENAME}\.gz" -s
RewriteRule "^(.*)\.css" "$1\.css\.gz" [QSA]
# Serve gzip compressed JS files if they exist
# and the client accepts gzip.
RewriteCond "%{HTTP:Accept-encoding}" "gzip"
RewriteCond "%{REQUEST_FILENAME}\.gz" -s
RewriteRule "^(.*)\.js" "$1\.js\.gz" [QSA]
# Serve correct content types, and prevent mod_deflate double gzip.
RewriteRule "\.css\.gz$" "-" [T=text/css,E=no-gzip:1]
RewriteRule "\.js\.gz$" "-" [T=text/javascript,E=no-gzip:1]
<FilesMatch "(\.js\.gz|\.css\.gz)$">
# Serve correct encoding type.
Header append Content-Encoding gzip
# Force proxies to cache gzipped &
# non-gzipped css/js files separately.
Header append Vary Accept-Encoding
</FilesMatch>

Apache - serving pre-compressed gzip file doesn't work

I'm having trouble using the rewrite rules for Apache (2.4) to serve compressed files.
My javascript bundling process generate .gz files for every .js it creates. I've activated the rewrite module on apache a2enmod rewrite and set the .htacess file like this:
AddEncoding gzip .gz
RewriteEngine on
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{REQUEST_FILENAME}\.gz -s
RewriteRule "^(.*)\.js" "$1\.js\.gz" [QSA]
# Serve correct content types, and prevent mod_deflate double gzip.
RewriteRule "\.js\.gz$" "-" [T=text/javascript,E=no-gzip:1]
<FilesMatch ".+\.(js\.gz)$">
Header append Content-Encoding gzip
Header append worked yes
</FilesMatch>
The problems I'm running are:
The first condition RewriteCond %{HTTP:Accept-encoding} gzip never evaluates to true. On Chrome Developer tools the client is sending this header Accept-Encoding:gzip, deflate, br (I've tried adding gzip, deflate, br to the condition but it doesn't work);
Even if I take this above condition out I can't see the header Content-Encoding in Chrome dev-tools;
I don't see Content-length in response headers. But it responds with a Transfer-Encoding:chunked which I find weird;
These are the modules that are enabled on my apache (I think they are enabled by default in my ubuntu dist because I didn't active any of those)
access_compat.load authz_user.load filter.load rewrite.load
alias.conf autoindex.conf headers.load setenvif.conf
alias.load autoindex.load mime.conf setenvif.load
auth_basic.load deflate.conf mime.load status.conf
authn_core.load deflate.load mpm_event.conf status.load
authn_file.load dir.conf mpm_event.load
authz_core.load dir.load negotiation.conf
authz_host.load env.load negotiation.load
The code you have there looks correct and seems to work fine on my computer, which suggests the problem is elsewhere. Some possibilities I can think of:
Perhaps a cache server/reverse proxy is messing with things (that would be my first guess, unless you're testing on localhost or set up everything yourself or otherwise know there isn't such a server)
Or perhaps mod_deflate is interfering anyways (I don't seem to have it installed on my computer so I can't test it); if you have access to the main server configuration maybe try commenting out the LoadModule line for it?
If any subdirectory has a .htaccess file that also uses rewrite rules, then rewrite rules in the parent directory won't run. (If this is the issue, RewriteOptions Inherit should work with these specific rules. However, this wouldn't explain the chunked encoding.)
Force refresh or clear cache in your browser?

Why is this simple CORS GET failing?

I have a server running apache. The .htaccess contains the following:
<IfModule mod_headers.c>
<FilesMatch "\.(eot|ttf|otf|woff|css)$">
Header add Access-Control-Allow-Origin "*"
</FilesMatch>
</IfModule>
Why is it that
$.get('https://www.sarahlawrence.edu/_assets/v6/fonts/otama-text-regular/otamatextregular.eot')`
works (try it in the console from any domain), whereas
$.get('https://www.sarahlawrence.edu/_assets/v6/lib/icons.data.svg.css')
fails with this error:
XMLHttpRequest cannot load https://www.sarahlawrence.edu/_assets/v6/lib/icons.data.svg.css. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://whatever.com' is therefore not allowed access.
And how can I get it working?
The missing Header can be confirmed using curl:
curl -v https://www.sarahlawrence.edu/_assets/v6/fonts/otama-text-regular/otamatextregular.eot > delme.txt
curl -v https://www.sarahlawrence.edu/_assets/v6/lib/icons.data.svg.css > delme.txt
The regex should be happy with the filename so I expect that the problem is either because there is a conflicting configuration somewhere in the apache configuration.
Another diagnostic check would be to copy the failing file into the fonts directory and check whether the header is present - this will confirm that the regex or the filename isn't the problem but indicates that it is directory configuration related.
You have stated that there are no other .htaccess files in the document root or children ( this could cause the problem ) and the file is being served just without the headers.
My feeling at this stage is that this may be related to your mod_pagespeed which is disabled for lib/icons. It could even come down to the ordering of the modules being loaded.
Trivially I would first restart your apache just in case. Any caching or proxy infrastructure in between should be disabled. Next I would disable mod_pagespeed and see if the issue remains.
I would also check to see whether there is a block of configuration in either your httpd.conf or the virtual hosts configuration that is similar as it is possible that this is catching some directories and not others and that your .htaccess is not doing what is expected. As a further check I would try removing or temporarily renaming .htaccess ( to htaccess-removed or something similar ) to confirm that the URL request headers are no longer being included using the curl or other approaches to validating the CORS headers.
Probably not related however another thing I'd check is the permissions and ownership of the files and directories - thought worth mentioning just in case.
Also worth checking the error logs on restarting the apache and on making the requests as this may provide further insight.
What is the full path to your .htaccess file?
Ether your .htaccess file is not set up in a way to have it apply it's rules to files in the https://www.sarahlawrence.edu/_assets/v6/lib/ location, or there is another rule somewhere else superseding the rule you have shown above.

apache mod_proxy, configuring ProxyPass & ProxyPassReverse for cross-domain ajax calls

I'm creating an html5 - JavaScript app (for mobile devices, using PhoneGap). I have to interact with a REST service.
The service is now running on "http://localhost:8080/backend/mvc/"
I'm developing my app on an wamp server (apache2) (http://localhost/stage/)
I'm using Chrome for browser.
when preforming an ajax call the browser responds: XMLHttpRequest cannot load http://localhost:8080/backend/mvc/event. Origin http://localhost is not allowed by Access-Control-Allow-Origin.
So I find several ways to circumvent this cross-domain ajax call problem:
1) starting chrome chrome.exe --disable-web-security
=> no difference
2) configuring apache using mod_proxy to redirect the traffic.
I enabled in the httpd.conf:
proxy_module
proxy_connect_module
proxy_http_module
I put a .htaccess file in the www root with the following content:
# start mod_rewrite
RewriteEngine On
ProxyRequests off
<Proxy>
Order deny,allow
Allow from all
</Proxy>
ProxyPass /EMBackend/ http://localhost:8080/backend/mvc/
ProxyPassReverse /EMBackend/ http://localhost:8080/backend/mvc/
RewriteRule ^/EMBackend/(.*)$ /backend/mvc/$1 [R]
I restarted all services (apache,php,..)
resulting in error 500
apache error log: [Tue Oct 18 14:30:11 2011] [alert] [client 127.0.0.1] C:/wamp/www/.htaccess: ProxyRequests not allowed here
Any clues on how to resolve this?
I found a working solution:
Enable:
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
Put this in the main section of your configuration (or desired virtual host, if using Apache virtual hosts):
ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass /EMBackend http://localhost:8080/backend/mvc
ProxyPassReverse /EMBackend http://localhost:8080/backend/mvc
<Location /EMBackend>
Order allow,deny
Allow from all
</Location>
So I guess I can't put it in .htaccess or I had to set ProxyPreserveHost On. I put Include conf/extra/ in the httpd.conf file and created the httpd-proxy.conf file and put the script above in it. Restarted apache and it's working!
You could simply add the given lines in the httpd.conf after enabling the proxy modules.
ProxyPreserveHost On
ProxyPass /EMBackend http://localhost:8080/backend/mvc
ProxyPassReverse /EMBackend http://localhost:8080/backend/mvc
Just restart the server and you are done.
In very modern apache, turn on proxy by:
a2enmod proxy;
a2enmod proxy_http

Categories