httprb / http

HTTP (The Gem! a.k.a. http.rb) - a fast Ruby HTTP client with a chainable API, streaming support, and timeouts
MIT License
3.01k stars 321 forks source link

Not working on Apple Silicon (M1) - libhttp-parser-ext.bundle: mach-o, but wrong architecture #630

Closed rgaufman closed 3 years ago

rgaufman commented 3 years ago

I have this simple script:

require 'bundler/inline'

gemfile do
  source 'https://rubygems.org'
  gem 'http'
end

response = HTTP.post('http://example.com', json: nil)

I also tried with gem 'http', github: 'httprb/http'

I get this output:

Romans-MacBook-Air.local ➜  scripts git:(master) ✗ ruby test-http.rb
Traceback (most recent call last):
    24: from test-http-arse.rb:6:in `<main>'
    23: from /opt/homebrew/Cellar/ruby/2.7.2/lib/ruby/2.7.0/bundler/inline.rb:54:in `gemfile'
    22: from /opt/homebrew/Cellar/ruby/2.7.2/lib/ruby/2.7.0/bundler/settings.rb:124:in `temporary'
    21: from /opt/homebrew/Cellar/ruby/2.7.2/lib/ruby/2.7.0/bundler/inline.rb:70:in `block in gemfile'
    20: from /opt/homebrew/Cellar/ruby/2.7.2/lib/ruby/2.7.0/bundler/runtime.rb:58:in `require'
    19: from /opt/homebrew/Cellar/ruby/2.7.2/lib/ruby/2.7.0/bundler/runtime.rb:58:in `each'
    18: from /opt/homebrew/Cellar/ruby/2.7.2/lib/ruby/2.7.0/bundler/runtime.rb:69:in `block in require'
    17: from /opt/homebrew/Cellar/ruby/2.7.2/lib/ruby/2.7.0/bundler/runtime.rb:69:in `each'
    16: from /opt/homebrew/Cellar/ruby/2.7.2/lib/ruby/2.7.0/bundler/runtime.rb:74:in `block (2 levels) in require'
    15: from /opt/homebrew/Cellar/ruby/2.7.2/lib/ruby/2.7.0/bundler/runtime.rb:74:in `require'
    14: from /opt/homebrew/lib/ruby/gems/2.7.0/gems/http-4.4.1/lib/http.rb:8:in `<top (required)>'
    13: from /opt/homebrew/lib/ruby/gems/2.7.0/gems/http-4.4.1/lib/http.rb:8:in `require'
    12: from /opt/homebrew/lib/ruby/gems/2.7.0/gems/http-4.4.1/lib/http/client.rb:9:in `<top (required)>'
    11: from /opt/homebrew/lib/ruby/gems/2.7.0/gems/http-4.4.1/lib/http/client.rb:9:in `require'
    10: from /opt/homebrew/lib/ruby/gems/2.7.0/gems/http-4.4.1/lib/http/connection.rb:6:in `<top (required)>'
     9: from /opt/homebrew/lib/ruby/gems/2.7.0/gems/http-4.4.1/lib/http/connection.rb:6:in `require'
     8: from /opt/homebrew/lib/ruby/gems/2.7.0/gems/http-4.4.1/lib/http/response/parser.rb:3:in `<top (required)>'
     7: from /opt/homebrew/lib/ruby/gems/2.7.0/gems/http-4.4.1/lib/http/response/parser.rb:3:in `require'
     6: from /opt/homebrew/lib/ruby/gems/2.7.0/gems/http-parser-1.2.2/lib/http-parser.rb:5:in `<top (required)>'
     5: from /opt/homebrew/lib/ruby/gems/2.7.0/gems/http-parser-1.2.2/lib/http-parser.rb:5:in `require'
     4: from /opt/homebrew/lib/ruby/gems/2.7.0/gems/http-parser-1.2.2/lib/http-parser/ext.rb:6:in `<top (required)>'
     3: from /opt/homebrew/lib/ruby/gems/2.7.0/gems/http-parser-1.2.2/lib/http-parser/ext.rb:8:in `<module:HttpParser>'
     2: from /opt/homebrew/lib/ruby/gems/2.7.0/gems/ffi-1.13.1/lib/ffi/library.rb:99:in `ffi_lib'
     1: from /opt/homebrew/lib/ruby/gems/2.7.0/gems/ffi-1.13.1/lib/ffi/library.rb:99:in `map'
/opt/homebrew/lib/ruby/gems/2.7.0/gems/ffi-1.13.1/lib/ffi/library.rb:145:in `block in ffi_lib': Could not open library '/opt/homebrew/lib/ruby/gems/2.7.0/gems/http-parser-1.2.2/ext/arm-darwin/libhttp-parser-ext.bundle': dlopen(/opt/homebrew/lib/ruby/gems/2.7.0/gems/http-parser-1.2.2/ext/arm-darwin/libhttp-parser-ext.bundle, 5): no suitable image found.  Did find: (LoadError)
    /opt/homebrew/lib/ruby/gems/2.7.0/gems/http-parser-1.2.2/ext/arm-darwin/libhttp-parser-ext.bundle: mach-o, but wrong architecture
    /opt/homebrew/lib/ruby/gems/2.7.0/gems/http-parser-1.2.2/ext/arm-darwin/libhttp-parser-ext.bundle: stat() failed with errno=25

From what I can tell http-parser is no longer maintained and was replaced by llhttp

Is there any solution to getting this gem working on Apple Silicon?

tarcieri commented 3 years ago

See #604 and #622 for ongoing discussion about replacing the parser

rgaufman commented 3 years ago

Ah, I see, thank you. I think I'm going to switch to Faraday for the time being until I can run httprb again.

DaniG2k commented 3 years ago

+1

tarcieri commented 3 years ago

Switching to llhttp seems like the way forward here. Please see https://github.com/httprb/http/pull/639 for progress.

tarcieri commented 3 years ago

So it seems there is a general problem with MRI C extensions on the M1. See a similar issue here: https://github.com/socketry/nio4r/pull/260

This seems like potentially a general upstream issue in MRI.

I would encourage anyone interested in helping resolve this issue to test out llhttp on an M1. It would be encouraging to know whether it will resolve this issue or not.

cc @bryanp

bryanp commented 3 years ago

FYI I'm attempting to track down an M1 to test out llhttp.

bryanp commented 3 years ago

I acquired an M1 Mini for testing and confirmed that llhttp works correctly. That being said, I cannot reproduce the original issue. I tried it both with brew installed ruby (2.7.2) and a compiled ruby via ruby-install (3.0.0). Both appear to work.

@rgaufman Can you offer any more input here?

tarcieri commented 3 years ago

On https://github.com/socketry/nio4r/pull/260 the issue appears to only (or at least, mostly) occur with system Ruby

bryanp commented 3 years ago

Right, but it looks like @rgaufman is using a brew installed version. Maybe the brewed version has been updated recently?

nitrnitr commented 3 years ago

Fixing the http-version on the Gemfile did it for me, new version has this fixed

gem 'http-parser', '~> 1.2.3'

ixti commented 3 years ago

master branch (future 5.0.0) is now using llhttp, so closing this ticket.