Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not able to properly parse using ruby FFI #43

Open
HoneyryderChuck opened this issue Jul 17, 2018 · 1 comment
Open

Not able to properly parse using ruby FFI #43

HoneyryderChuck opened this issue Jul 17, 2018 · 1 comment

Comments

@HoneyryderChuck
Copy link

Hi, I'm trying to create an FFI binding for ruby. Unfortunately, haven't been able to progress in the most basic example, as I can't get the verb and path strings back. Since I'm a bit out of ideas on how to further debug it, came asking for advice. I've contained it in a small-purpose script:

# tested with ruby 2.5 and 24, ruby-ffi 1.9.25
require 'ffi'

module Ext
  extend FFI::Library
  ffi_lib './ext/x86_64-darwin/libpico-http-parser-ext.bundle'
  attach_function :phr_parse_request, [:pointer, :size_t, :pointer, :pointer, :pointer, :pointer, :pointer, :pointer, :pointer, :size_t], :int
end

REQUEST = +"GET /test?ok=1 HTTP/1.1\r\nUser-Agent: curl/7.18.0\r\nHost: 0.0.0.0:5000\r\nAccept: */*\r\nContent-Length: 5\r\n\r\nWorld".b

verb = FFI::MemoryPointer.new(:pointer)
verb_len = FFI::MemoryPointer.new(:size_t)
path = FFI::MemoryPointer.new(:pointer)
path_len = FFI::MemoryPointer.new(:size_t)
minor_version = FFI::MemoryPointer.new(:int)
header_reader = FFI::MemoryPointer.new(:pointer)
header_reader_len = FFI::MemoryPointer.new(:int)
header_reader_len.write_int(128)

res = Ext.phr_parse_request(REQUEST, REQUEST.bytesize, verb, verb_len, path, path_len, minor_version, header_reader, header_reader_len, 0)

puts "bytes parsed: #{res}"
puts "method: #{verb.read_string(verb_len.read_int).inspect}"
puts "path: #{path.read_string(path_len.read_int).inspect}"
puts "version: HTTP/1.#{minor_version.read_int.inspect}"

# bytes parsed: 104
# method: "0d\x98"
# in `get_bytes': Memory access offset=0 size=10 is out of bounds (IndexError)

@kazuho did you have some success using ffi in any other language? I've seen your perl parser and also @kazeburo 's ruby c-extension binding, but sadly neither could help get to the bottom of this. Some ruby-FFI-specific issue?

@larskanis
Copy link

You need to allocate some memory for data not just pointers, like so:

verb = FFI::MemoryPointer.from_string("GET")
verb_len = FFI::MemoryPointer.new(:size_t)
verb_len.write(:size_t, verb.size-1)
header_reader = FFI::MemoryPointer.new(128)
header_reader_len = FFI::MemoryPointer.new(:int)
header_reader_len.write_int(128)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants