Rails: Puma MiniSSL::SSLError

The problem

When setting up a dev environment for older Rails projects, Puma can sometimes have trouble serving https:// pages. Puma boots ok but will begin choking with a MiniSSL::SSLError:

➜ bundle exec rails s -b "ssl://0.0.0.0:3000?key=config/ssl.key&cert=config/ssl.crt"
=> Booting Puma
=> Rails 6.0.4.1 application starting in development

2022-03-03 17:19:21 +1100: SSL error, peer: 127.0.0.1, peer cert: , # <Puma::MiniSSL::SSLError: OpenSSL error: error:141F7065:SSL routines:final_key_share:no suitable key share - 337604709>

The fix

This error is caused by a bug in older versions of Puma. To fix, simply update the version of Puma in the Rails gemfile:

/Gemfile
#gem 'puma', '~> 3.11'
gem 'puma', '~> 4.3.8'

Then install the new version of the Puma gem and test:

➜ bundle install
➜ bundle exec rails s -b "ssl://0.0.0.0:3000?key=config/ssl.key&cert=config/ssl.crt"
=> Booting Puma
=> Rails 6.0.4.1 application starting in development

Puma should now run and serve https pages successfully.

Rails 6 & Node: Yarn error on install around ‘remove_cv_t’

This error can occur when setting up a development environment for an existing Rails 6 project and the node dependencies are being installed. It seems to be caused by an incompatibility between node-sass and Node 16.

Here are step by step instructions on how to fix the problem by specifying the version of node to use in the project folder using NVM.

➜ bundle exec rails server # rails won't boot, yarn error
...
========================================
  Your Yarn packages are out of date!
  Please run `yarn install --check-files` to update.
========================================

➜ yarn install --check-files # yarn install fails...
...
/Users/user/.node-gyp/16.13.1/include/node/v8-internal.h:492:38: error: no template named 'remove_cv_t' in namespace 'std'; did you mean 'remove_cv'?

➜ brew install nvm # install Node Version Mgr if needed
➜ echo "14.18.2" > .nvmrc # create a version file for NVM (do this in your rails project directory)
➜ cat .nvmrc
14.18.2

➜ node -v # check the current node version
v16.13.1

➜ nvm use
Found '/Users/user/project/.nvmrc' with version <14.18.2>
Now using node v14.18.2 (npm v6.14.15)

➜ node -v # verify we're now using the correct node version
v14.18.2

➜ yarn install --check-files # install should now complete ok
...
✨  Done in 8.73s.

➜ bundle exec rails server # rails should now boot
=> Booting Puma

Here’s the full error trace:

In file included from /Users/user/.node-gyp/16.13.1/include/node/v8.h:30:
/Users/user/.node-gyp/16.13.1/include/node/v8-internal.h:492:38: error: no template named 'remove_cv_t' in namespace 'std'; did you mean 'remove_cv'?
            !std::is_same<Data, std::remove_cv_t<T>>::value>::Perform(data);
                                ~~~~~^~~~~~~~~~~
                                     remove_cv
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/type_traits:710:50: note: 'remove_cv' declared here
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_cv
                                                 ^
1 error generated.
make: *** [Release/obj.target/binding/src/binding.o] Error 1
gyp ERR! build error
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/Users/user/project/node_modules/node-gyp/lib/build.js:262:23)
gyp ERR! stack     at ChildProcess.emit (node:events:390:28)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (node:internal/child_process:290:12)
gyp ERR! System Darwin 21.2.0
gyp ERR! command "/Users/user/.nvm/versions/node/v16.13.1/bin/node" "/Users/user/project/node_modules/node-gyp/bin/node-gyp.js" "rebuild" "--verbose" "--libsass_ext=" "--libsass_cflags=" "--libsass_ldflags=" "--libsass_library="
gyp ERR! cwd /Users/user/project/node_modules/node-sass
gyp ERR! node -v v16.13.1
gyp ERR! node-gyp -v v3.8.0
gyp ERR! not ok

Fix incorrect GIT author for multiple commits

I have separate GIT identities for my personal and client coding, and sometimes I’ve been working on a new codebase for a while under the wrong identity without noticing. This can be super fiddly to fix on a per-commit basis with the command line.

Here is a blunt-force way to change ALL of your personal commits to match your work account, without affecting other contributor history. ALWAYS make a copy of your project folder before attempting this kind of surgery as it can blat your entire repo history.

➜ git config user.email
[email protected] # oops wrong identity

➜ git config user.name “My Name”
➜ git config user.email “[email protected]

git filter-branch --env-filter 'if [ "$GIT_AUTHOR_EMAIL" = "[email protected]" ]; then [email protected]; GIT_AUTHOR_NAME="My Name"; GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL; GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; fi' -- --all

(read the scary warning and press <enter>)

Proceeding with filter-branch…
Rewrite 0ba49ecf8d03eacdbe082cbc6616c528efa7e839 (2263/2268) (164 seconds passed, remaining 0 predicted)
Ref 'refs/heads/develop' was rewritten
Ref 'refs/heads/feature/my-feature' was rewritten

I recommend immediately pushing to your remote repo and checking that the commit history looks ok so you can roll back if needed.

RSpec error – Host header or origin header is specified and is not whitelisted or localhost.

I encountered the following head-scratcher when trying to run the following RSpec test on MacOs:

➜ bundle exec rspec ./spec/features/some_spec.rb:12
...

Capybara starting Puma…
Version 4.3.8 , codename: Mysterious Traveller
Min threads: 0, max threads: 4
Listening on tcp://127.0.0.1:63422
...

Selenium::WebDriver::Error::WebDriverError:
unexpected response, code=500, content-type="text/html"
Host header or origin header is specified and is not whitelisted or localhost.


After much fruitless poking around in ./spec/rails_helper.rb, I checked my /etc/hosts file and realised I had mapped 127.0.0.1 to a custom name. I updated /etc/hosts to include only the following lines:

127.0.0.1 localhost
0.0.0.0 my.localdev


And hey presto, Selenium would now run the rest of my (still failing) tests.

As an aside, I tried passing the options '--headless', '--disable-web-security', '-–allow-file-access-from-files', '--allowed-origins=*‘ to Capybara in ./spec/rails_helper.rb, and none seemed to have any effect.

Rails HTTPs error on localhost – getaddrinfo SocketError

I recently began developing a Rails Plugin gem, and running the dummy app locally using HTTP worked flawlessly out of the box. However, when it came time to test HTTPS, I encountered the following error:

➜ rails s -b "ssl://0.0.0.0:3000?key=config/cert.key&cert=config/cert.crt"
=> Booting WEBrick
=> Rails 5.2.6 application starting in development on http://ssl://0.0.0.0:3000?key=config/cert.key&cert=config/cert.crt:3000
=> Run rails server -h for more startup options
INFO WEBrick 1.4.4
`getaddrinfo': getaddrinfo: nodename nor servname provided, or not known (SocketError)

This was puzzling at first as I had other apps running fine using HTTPS. After closer inspection I discovered the other apps were running under the Puma webserver, while my gem had defaulted to using WEBrick.

Solution

The solution was to find the latest version of Puma and add it to my gem:

➜ gem search puma
*** REMOTE GEMS ***
...
puma (5.5.2 ruby java java, 5.4.0, 4.3.10)
...

edit ./Gemfile:
...
gem "puma", "5.5.2"
...

Install the gem:

➜ bundle install
...
Installing puma 5.5.2 with native extensions
...

The Rails app then booted into HTTPs successfully under Puma:

➜ rails s -b "ssl://0.0.0.0:3000?key=config/cert.key&cert=config/cert.crt"
=> Booting Puma
...
Listening on ssl://0.0.0.0:3000?key=config/cert.key&cert=config/cert.crt


Error when installing Rubocop globally on Macos using rbenv and homebrew

To use the Rubocop gem with VSCode to assist with code linting, it’s sometimes desirable to have Rubocop installed at the system level. I recently ran into a permissions problem when using the homebrew version of Ruby to install Rubocop, and this was the solution:

➜ gem install rubocop
ERROR: While executing gem … (Gem::FilePermissionError)
You don’t have write permissions for the /Library/Ruby/Gems/2.6.0 directory.
➜ rbenv install -l
➜ rbenv install 3.0.2
➜ rbenv global 3.0.2
➜ ruby --version

ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-darwin20]
➜ gem install rubocop

(long pause)

Done installing documentation for unicode-display_width, ruby-progressbar, ast, parser, rubocop-ast, regexp_parser, rainbow, parallel, rubocop after 24 seconds
9 gems installed

Rails: Error installing gem mysql2 on MacOs

When installing gems on a new project under MacOs using bundler, I encountered the following error for MySql:

Installing mysql2 0.5.2 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

linking shared-object mysql2/mysql2.bundle
ld: library not found for -lssl
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [mysql2.bundle] Error 1

It seems the clang compiler couldn’t find an SSL library on the system. The solution was:

> brew install openssl
> bundle config --global build.mysql2 --with-opt-dir="$(brew --prefix openssl)
> bundle

# This also works:
> export LIBRARY_PATH=$LIBRARY_PATH:/usr/local/opt/openssl/lib/

SquareSpace SEO – fixing default robots tag

I recently used the SquareSpace platform to throw together a quick company demonstration website. However even after weeks, the website wasn’t showing up in Google results.

It turns out that, by default, SquareSpace will insert a <meta name="robots" content="noindex,nofollow"> tag into the homepage! What a truly bizarre preset, as it completely nerfs your site’s SEO. Even worse, the tag cannot be configured using the site builder user interface!

The solution is to edit the page in SquareSpace and use the Advanced -> Code Injection option to manually override the <meta> tag with the correct content of <meta name="robots" content="index,follow"> as shown in the screenshots below.

My site is now indexing correctly and showing in the first SERP page. You can confirm that the tag configration has worked using the SEO Site Checkup NoIndex Tag Test webapp.

Once your homepage has the corrected <meta> tag, use Google’s URL Inspection tool to request a recrawl of the site (as per the Google Developer Docs). You can also submit the SquareSpace sitemap, which by default is set to https://www.yourwebsite.com/sitemap.xml.

Your page should now begin to have increased visiblity in Google within a couple of days.

Screenshots for SquareSpace configration:

Screenshots for Google Search Console configuration:

Search Console URL: https://search.google.com/search-console

Remapping Caps Lock to Control and Escape in macOS Big Sur

For more better text editing and great success.

I’m a big fan of VIM modal editing and keeping keyboard shortcuts as close to the home row as possible. This philosophy allows fluid text editing and staying in the “programming flow state”.

Remapping the Caps Lock key to Control and Escape is a big part of this workflow. Pressing and releasing sends the Escape key, while pressing and holding emulates the Control Key.

In macOS, I’d been using Karabiner Elements to enable this remapping, however with macOS Big Sur I could no longer get the configuration to work. This was a serious annoyance, since the VIM shortcuts are burned into my fingertips.

Enter HammerSpoon! Using the ControlEscape plugin, I am now back in remapping bliss. Below are the System Preference settings required to make this setup work.