CORS errors in development caused by puma-dev serving public files directly
Pezmc opened this issue · comments
When using a symlink, puma-dev serves files from the public directory that exist directly without proxying the request (added in 49fdcf3 to address #44):
Lines 150 to 157 in 458cc5c
Unfortunately, this is causing issues in development for any scripts loaded using type=module
built by webpacker that are served from a different subdomain. When not running ./bin/webpack-dev-server
, rails runs ./bin/webpack
internally, which puts scripts in the public/packs/
folder. Puma-dev is serving these directly meaning any middleware that sets up CORS headers isn't running.
An option to turn off direct serving of files from public/ or another way to force those files to be served via rails (so middleware runs), is one option to resolve this issue.
For example our setup is as follows:
config/development.rb
adds a middleware that setsAccess-Control-Allow-Origin: *
to all .js files- Assets are served from cache subdomain using
config.action_controller.asset_host = 'cache.exampleapp.localhost'
- A JS file, built by webpacker, is added to the page on a subdomain using
type=module
(javascript_pack_tag :script, type: 'module'
) - puma-dev is setup using
puma-dev link
in theexampleapp
directory - On boot, rails runs
./bin/webpack
which puts files underexampleapp/public/packs/
- puma-dev serves those files directly, rather than them going via the middleware
- app falls over with the below error:
Access to script at 'https://cache.exampleapp.localhost/packs/js/reports/script-9ba4a6d41b4d049ca1fa.js' from origin 'https://main.exampleapp.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
filter:1463 GET https://cache.exampleapp.com/packs/js/reports/script-9ba4a6d41b4d049ca1fa.js net::ERR_FAILED```
An option to turn off direct serving of files from public/ or another way to force those files to be served via rails (so middleware runs), is one option to resolve this issue.
A -no-serve-public
flag to opt-out of serving seams straightforward enough, esp if you're ok with disabling it globally. Do you expect all apps running under puma-dev to behave this way?
@nonrational In our particular case, disabling globally is likely going to be fine; however I do wonder if more and more people are going to start hitting similar problems now webpacker is the default for Rails!
Maybe providing a matcher like -ignored-static-paths='/public/packs:/public/foo'
would be better. We could decide to make the default value non-empty at a later date. And, you could disable it entirely with -ignored-static-paths='/public'
I think that's a great approach!
@nonrational Is there any way I can help here? The team impacted by the above is still a frustrating work around and I'd love to try and sort it out!
Sorry for the delay I saw your PR but I've been away, looking into it now!
Hmm, I uninstalled the old binary using:
puma-dev -stop
Then built a binary of this branch with
make && make install
Then ran:
./puma-dev -install -d test:localhost -no-serve-public-paths .
Checking ~/Library/LaunchAgents/io.puma.dev.plist
I didn't see the argument added, so I modified the file to:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>io.puma.dev</string>
<key>ProgramArguments</key>
<array>
<string>/Users/pezcuckow/Git/puma-dev/puma-dev</string>
<string>-launchd</string>
<string>-dir</string>
<string>~/.puma-dev</string>
<string>-d</string>
<string>test:localhost</string>
<string>-timeout</string>
<string>15m0s</string>
<string>-no-serve-public-paths</string>
<string>.</string>
</array>
...
And restarted the launch agent:
$ launchctl unload ~/Library/LaunchAgents/io.puma.dev.plist
$ ./puma-dev -stop
$ launchctl load ~/Library/LaunchAgents/io.puma.dev.plist
And I'm still seeing the same CORS errors where files in /public appear to be being served by Puma:
Note no CORS headers, files served by Rails look like this:
Note the Access-Control-Allow-Origin: *
Perhaps I've configured Puma-Dev wrong?
@Pezmc #262 will allow you to set
-no-serve-public-paths='/packs'
You need to provide an argument (a :
separated string of paths like /packs:/foo:/bar:/baz
) to the flag.
However, I neglected to update the plist template to ensure that this config will be respected by -install
. As is, It will only work in the foreground. 😅
Aah, I thought -no-serve-public-paths .
would pass that, trying again!
I'm surprised it didn't work when I manually modified the plist though!
Confirmed working, I opened a PR to add the plist support and some simple logging of the new option: #263