tmm1 / http_parser.rb Goto Github PK
View Code? Open in Web Editor NEWThis project forked from macournoyer/ruby_http_parser
simple callback-based HTTP request/response parser
License: MIT License
This project forked from macournoyer/ruby_http_parser
simple callback-based HTTP request/response parser
License: MIT License
Little surprised nobody has reported this earlier ...
Re-building http_parser.rb with the latest version of http-parser (2.9.4) I noticed the "post identity body world" check fails:
1) HTTP::Parser should parse request: post identity body world
Failure/Error: @parser << test['raw']
HTTP::Parser::Error:
Could not parse data entirely (116 != 122)
# ./spec/parser_spec.rb:317:in `<<'
# ./spec/parser_spec.rb:317:in `block (4 levels) in <top (required)>'
After a lengthy research I think the test is indeed flawed, i.e. in violation of RFC 7320 3.3.1. ("Transfer-Encoding").
The check sets Transfer-Encoding: identity
and also Content-Length: 5
About the first, the RFC states:
If any transfer coding
other than chunked is applied to a request payload body, the sender
MUST apply chunked as the final transfer coding to ensure that the
message is properly framed.
...so this is not acceptable.
According to 3.3.3. ("Message Body Length"), combining Transfer-Encoding: and Content-Length: indicate "request smuggling" which "ought to be handled as an error" - which is what the http-parser library now does: It implemented a stricter check in commit nodejs/http-parser@7d5c99d.
Reproducer (could possibly be shorter):
require "http/parser"
parser = Http::Parser.new
parser.on_headers_complete = proc do
p parser.http_version
p parser.http_method # for requests
p parser.request_url
p parser.status_code # for responses
p parser.headers
end
parser <<"POST /post_identity_body_world?q=search#hey HTTP/1.1\r\nAccept: */*\r\nContent-Length: 5\r\nTransfer-Encoding: identity\r\n\r\nWorld"
Solution: Please rewrite or disable that test.
I'm trying to set up your t program on my Beaglebone A6 to send and receive tweets from the device. However, when I run "gem install t" I get an error saying that ryah_http_parser.h cannot find sys/types.h. When I edit the ryah_http_parser.h file to point to /usr/include/sys/types.h, and run "$ gem install t" again, I get the same error and the alteration I made to the .h file has been overwritten.
I can't find the point where the gem installer is rewriting ryah_http_parser.h, thus I can't get this filepath change to stick. I don't know anything about ruby, although I'm running the latest version available (1.9.3) which the readme says should work. Do you have any advice?
Version https://rubygems.org/gems/http_parser.rb/versions/0.6.1 was pushed today.
However only the MRI variant - the JRuby (-java) platfom version was not released.
Could we gem a proper release including the -java version pushed, please? // cc @ashie
❤️
Hello ,i am new to ROR. i added "gem 'http_parser.rb', '~> 0.6.0'" in gemfile and hit bundle command in command prompt.it gave me the following error.Can you please help me to resolve this error.?
Error:
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
C:/Ruby193/bin/ruby.exe -r ./siteconf20141218-3932-nyliv2.rb extconf.rb
creating Makefile
make clean
Makefile:165: *** target pattern contains no `%'. Stop.
make
Makefile:165: *** target pattern contains no `%'. Stop.
make failed, exit code 2
Gem files will remain installed in C:/Ruby193/lib/ruby/gems/1.9.1/gems/http_pars
er.rb-0.6.0 for inspection.
Results logged to C:/Ruby193/lib/ruby/gems/1.9.1/extensions/x86-mingw32/1.9.1/ht
tp_parser.rb-0.6.0/gem_make.out
An error occurred while installing http_parser.rb (0.6.0), and Bundler cannot
continue.
Make sure that gem install http_parser.rb -v '0.6.0'
succeeds before bundling.
Hello,
It looks like http_parser.rb, hasnt been released 2013 (0.6.0), since then, there have been a number of commits to master, specifically one which fixes a whitespace issue in the path. Can you please release version 0.6.1 of this package?
Thank you!
Shyam
I am using http parser with read_nonblock
. I've obtained a timeout or eof exceptions. I was image that on_message_complete
is a callback and it will be fired when the request or response has finished. But I was wrong.
it "should abort parser via header complete callback without a body" do
"GET / HTTP/1.0\r\n" +
"Content-Length: 0\r\n" +
"\r\n"
...
expect(@body).to be_empty
expect(@done).to be false
I have more absurd:
HTTP/1.1 200 Connection established\r\n
Connection: close\r\n
\r\n
The headers has finished but the message hasn't finished. What are you waiting for? Connection has been already closed.
Noticed something odd when trying to install the gem on Windows. Many windows users have a space in their username, and I normally run that way. I have not found any issues with it.
When I install the gem, I get an error during compile:
compiling ruby_http_parser.c
x86_64-w64-mingw32-gcc.exe: error: T/.gem/ruby/2.7.0/gems/http_parser.rb-0.6.0/ext/ruby_http_parser: No such file or directory
Which is the user gem folder split where the space exists. But, I don't have the problem when installing EventMachine. I assume it's something in extconf.rb
, but I'm not much of a c type...
If you have any interest in testing on Appveyor or building the gem there (or both), I'd be happy to help. Landed here wrestling with Jekyll...
When I do gem install http_parser.rb
, I see the file gems/http_parser.rb-0.6.0/Gemfile.lock installed, which has:
...
specs:
benchmark_suite (0.8.0)
diff-lcs (1.1.2)
ffi (1.0.11)
ffi (1.0.11-java)
json (1.8.0)
json (1.8.0-java)
rake (0.9.2)
rake-compiler (0.7.9)
rake
rspec (2.4.0)
rspec-core (~> 2.4.0)
rspec-expectations (~> 2.4.0)
rspec-mocks (~> 2.4.0)
rspec-core (2.4.0)
rspec-expectations (2.4.0)
diff-lcs (~> 1.1.2)
rspec-mocks (2.4.0)
yajl-ruby (1.1.0)
...
trivy reports some of those locked old version dependencies need upgrade:
+-----------+------------------+----------+-------------------+---------------+-----------------------------------------+
| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE |
+-----------+------------------+----------+-------------------+---------------+-----------------------------------------+
| ffi | CVE-2018-1000201 | HIGH | 1.0.11 | 1.9.24 | ruby-ffi DDL loading |
| | | | | | issue on Windows OS |
| | | | | | -->avd.aquasec.com/nvd/cve-2018-1000201 |
+ + + +-------------------+ + +
| | | | 1.0.11-java | | |
| | | | | | |
| | | | | | |
+-----------+------------------+ +-------------------+---------------+-----------------------------------------+
| json | CVE-2020-10663 | | 1.8.0 | 2.3.0 | rubygem-json: Unsafe Object |
| | | | | | Creation Vulnerability in JSON |
| | | | | | -->avd.aquasec.com/nvd/cve-2020-10663 |
+ + + +-------------------+ + +
| | | | 1.8.0-java | | |
| | | | | | |
| | | | | | |
+-----------+------------------+ +-------------------+---------------+-----------------------------------------+
| rake | CVE-2020-8130 | | 0.9.2 | 12.3.3 | rake: OS Command Injection |
| | | | | | via egrep in Rake::FileList |
| | | | | | -->avd.aquasec.com/nvd/cve-2020-8130 |
+-----------+------------------+ +-------------------+---------------+-----------------------------------------+
| yajl-ruby | CVE-2017-16516 | | 1.1.0 | 1.3.1 | rubygem-yajl-ruby: |
| | | | | | Yajl::Parser.new.parse |
| | | | | | incorrect parsing |
| | | | | | -->avd.aquasec.com/nvd/cve-2017-16516 |
+-----------+------------------+----------+-------------------+---------------+-----------------------------------------+
I'm going to remove these. Is anyone relying on them? // cc @igrigorik
We can add backwards compat methods to Http::Parser that return these values based on request_url
Upgrade support has been sitting in master for a while, can we get a new (official) gem version?
Please change
require "http/parser"
to
require "http_parser"
in "Usage" chapter
when i install arachni , i got a error gem install mini_portile2 -v '2.1.0'
,so i want to know how to install it..
Hello,
Could you mention whether or not it is expected for this library to support parse webdav http requests?
Can't install http_parser.rb-0.6.0 on Windows 8.1 x64 Ruby v1.9.3 ( http://rubyinstaller.org/ ):
Building native extensions. This could take a while...
ERROR: Error installing http_parser.rb:
ERROR: Failed to build gem native extension.
W:/Ruby193/bin/ruby.exe extconf.rb
creating Makefile
make
generating ruby_http_parser-i386-mingw32.def
compiling ruby_http_parser.c
ruby_http_parser.c:1:0: error: CPU you selected does not support x86-64 instruction set
#include "ruby.h"
^
ruby_http_parser.c:1:0: error: CPU you selected does not support x86-64 instruction set
make: *** [ruby_http_parser.o] Error 1
https://gist.github.com/05bf5df49899d45446bd
Calling reset! within the callback does not reset the parser to initial state and results in second request being passed in as a body callback.
Cannot load the gem.
$ rake -T
rake aborted!
cannot load such file -- 2.0/http11
...
The gem installation silently installed and just complained about documentation issues:
$ gem install http_parser.rb
Fetching: http_parser.rb-0.5.3.gem (100%)
Temporarily enhancing PATH to include DevKit...
Building native extensions. This could take a while...
Successfully installed http_parser.rb-0.5.3
Parsing documentation for http_parser.rb-0.5.3
unable to convert "\x90" from ASCII-8BIT to UTF-8 for lib/ruby_http_parser.so, skipping
Installing ri documentation for http_parser.rb-0.5.3
Done installing documentation for http_parser.rb (0 sec).
1 gem installed
This was gcc.exe (rubenvb-4.7.2-release) 4.7.2 and
Rails 3.2.13.rc1.
I've found a bug in the parser while testing some implementation here, and discovered that there's something wrong with the java parser, specifically: header callback is being called 2 times, and the last one after the #on_body calls, before the parsing is done. I've devised this test script to demonstrate:
require "http_parser"
$payload = "POST / HTTP/1.1\r\nAccept-Encoding: identity;q=1.0\r\nAccept: */*\r\nUser-Agent: Ruby\r\nHost: 127.0.0.1:58229\r\nTransfer-Encoding: chunked\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\nb\r\nonetwothree\r\n0\r\n\r\n".b
$parser = HTTP::Parser.new
$parser.on_message_begin = -> { puts "started!!!" }
$parser.on_headers_complete = -> (h) { puts "headers! #{h}" }
$parser.on_body = -> (ch) { puts "chunk! #{ch}" }
$parser.on_message_complete = -> { puts "we're done!!" }
$parser << $payload
# running with jruby-9.1.13.0
# started!!!
# headers! {"Accept-Encoding"=>"identity;q=1.0", "Accept"=>"*/*", "User-Agent"=>"Ruby", "Host"=>"127.0.0.1:58229", "Transfer-Encoding"=>"chunked", "Content-Type"=>"application/x-www-form-urlencoded"}
# chunk! onetwothree
# headers! {"Accept-Encoding"=>"identity;q=1.0", "Accept"=>"*/*", "User-Agent"=>"Ruby", "Host"=>"127.0.0.1:58229", "Transfer-Encoding"=>"chunked", "Content-Type"=>"application/x-www-form-urlencoded"}
# we're done!!
The CRuby implementation works as expected. I've also noticed that 2 tests are failing for jruby. Maybe that could be the issue(?).
I have seen that there is no trailer header support in the parser. Is it a difficult task to implement?
The way I see it, one would have to, on message complete, check whether there are trailers.
If no trailers available, done.
If trailers available, use the headers parser, call the same callback or a different callback (#on_trailer_headers_complete?) and call #on_message_complete.
% ruby --1.9 -e 'require "http/parser"; puts HTTP::Parser; puts HTTP::Parser.new'
HTTP::Parser
TypeError: wrong argument type unknown (expected Struct)
(root) at -e:1
% ruby --version
jruby 1.6.5 (ruby-1.8.7-p330) (2011-10-25 9dcd388) (OpenJDK 64-Bit Server VM 1.6.0_24) [linux-amd64-java]
% gem list http_parser.rb
http_parser.rb (0.5.3 ruby java)
Fails in JRuby 1.6.5 and 1.6.6. Let me know if you need any more information :)
Attempting to start a (very) legacy rails project after having updated the http_parser.rb
gem to version 0.8.0
.
/Users/username/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/activesupport-3.2.22.5/lib/active_support/dependencies.rb:251:in `require': dlopen(/Users/username/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/http_parser.rb-0.8.0/lib/ruby_http_parser.bundle, 0x0009): symbol not found in flat namespace '_rb_get_kwargs' - /Users/username/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/http_parser.rb-0.8.0/lib/ruby_http_parser.bundle (LoadError)
from /Users/username/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/activesupport-3.2.22.5/lib/active_support/dependencies.rb:251:in `block in require'
from /Users/username/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/activesupport-3.2.22.5/lib/active_support/dependencies.rb:236:in `load_dependency'
from /Users/username/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/activesupport-3.2.22.5/lib/active_support/dependencies.rb:251:in `require'
from /Users/username/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/http_parser.rb-0.8.0/lib/http_parser.rb:2:in `<top (required)>'
from /Users/username/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/activesupport-3.2.22.5/lib/active_support/dependencies.rb:251:in `require'
from /Users/username/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/activesupport-3.2.22.5/lib/active_support/dependencies.rb:251:in `block in require'
from /Users/username/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/activesupport-3.2.22.5/lib/active_support/dependencies.rb:236:in `load_dependency'
from /Users/username/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/activesupport-3.2.22.5/lib/active_support/dependencies.rb:251:in `require'
from /Users/username/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/http_parser.rb-0.8.0/lib/http/parser.rb:1:in `<top (required)>'
from /Users/username/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/activesupport-3.2.22.5/lib/active_support/dependencies.rb:251:in `require'
from /Users/username/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/activesupport-3.2.22.5/lib/active_support/dependencies.rb:251:in `block in require'
from /Users/username/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/activesupport-3.2.22.5/lib/active_support/dependencies.rb:236:in `load_dependency'
from /Users/username/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/activesupport-3.2.22.5/lib/active_support/dependencies.rb:251:in `require'
from /Users/username/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/em-http-request-1.1.7/lib/em-http.rb:4:in `<top (required)>'
from /Users/username/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/activesupport-3.2.22.5/lib/active_support/dependencies.rb:251:in `require'
from /Users/username/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/activesupport-3.2.22.5/lib/active_support/dependencies.rb:251:in `block in require'
from /Users/username/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/activesupport-3.2.22.5/lib/active_support/dependencies.rb:236:in `load_dependency'
from /Users/username/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/activesupport-3.2.22.5/lib/active_support/dependencies.rb:251:in `require'
from /Users/username/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/faye-1.0.1/lib/faye.rb:4:in `<top (required)>'
from /Users/username/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/bundler-1.17.3/lib/bundler/runtime.rb:81:in `require'
from /Users/username/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/bundler-1.17.3/lib/bundler/runtime.rb:81:in `block (2 levels) in require'
from /Users/username/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/bundler-1.17.3/lib/bundler/runtime.rb:76:in `each'
from /Users/username/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/bundler-1.17.3/lib/bundler/runtime.rb:76:in `block in require'
from /Users/username/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/bundler-1.17.3/lib/bundler/runtime.rb:65:in `each'
from /Users/username/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/bundler-1.17.3/lib/bundler/runtime.rb:65:in `require'
from /Users/username/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/bundler-1.17.3/lib/bundler.rb:114:in `require'
from /Users/username/Documents/GitHub/fms/config/application.rb:12:in `<top (required)>'
from /Users/username/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/railties-3.2.22.5/lib/rails/commands.rb:53:in `require'
from /Users/username/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/railties-3.2.22.5/lib/rails/commands.rb:53:in `block in <top (required)>'
from /Users/username/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/railties-3.2.22.5/lib/rails/commands.rb:50:in `tap'
from /Users/username/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/railties-3.2.22.5/lib/rails/commands.rb:50:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
Environment:
Mac OS Montery 12.1 (M1)
Ruby 2.1.1p76
Rails 3.2.22.5
Full code to reproduce this bug(?) here:
https://github.com/jordansissel/experiments/tree/master/ruby/http_parser#readme
I've copied part of the readme from above, here:
% grep failures output/*
output/[email protected]:2 tests, 2 assertions, 0 failures, 0 errors, 0 skips
output/[email protected]:2 tests, 2 assertions, 0 failures, 0 errors, 0 skips
output/[email protected]:2 tests, 2 assertions, 1 failures, 0 errors, 0 skips
output/[email protected]:2 tests, 2 assertions, 1 failures, 0 errors, 0 skips
output/[email protected]:2 tests, 2 assertions, 1 failures, 0 errors, 0 skips
This request parses properly:
request = buildrequest([
"GET /foo HTTP/1.1",
"host: localhost",
""
])
This request does not:
request = buildrequest([
"GET /websocket HTTP/1.1",
"host: localhost",
"connection: Upgrade",
"upgrade: websocket",
"sec-websocket-key: SD6/hpYbKjQ6Sown7pBbWQ==",
"sec-websocket-version: 13",
""
])
The failure is that parser << data
is returning an offset that is one byte
short:
% grep OFFSET output/*
output/[email protected]:OFFSET WRONG? Data remaining: "\n"
output/[email protected]:.OFFSET WRONG? Data remaining: "\n"
output/[email protected]:OFFSET WRONG? Data remaining: "\n"
Given the following code I get a Parser::Error, same with GET / HTTP/0.9
.
req = ""
req << "PATCH / HTTP/1.1\r\n"
req << "Host: 127.0.0.1:4567\r\n"
req << "Transfer-Encoding: chunked\r\n"
req << "\r\n"
req << "9\r\n"
req << "name=zack\r\n"
req << "0\r\n"
req << "\r\n"
require "http/parser"
parser = HTTP::Parser.new
parser.on_headers_complete = proc do
p parser.http_method
p parser.request_url
p parser.headers
end
parser.on_body = proc do |chunk|
p chunk
end
parser.on_message_complete = proc do
puts "finished!"
end
parser << req
Changed in this commit.
This causes a crash with http_parser.rb v0.6.0 with a java.lang.NoSuchMethodError.
See https://gist.github.com/bbozo/6157377
I've got a service class intended for Torquebox implementing start/stop/initialize, other then that it's nothing special, a basic PORO in which start
runs a thread which runs an EventMachine HTTP server which is a pretty common/basic/well tested use case for EM.
Anyway, when I run
x = HttpServerService.new; x.start
and execute a curl call to the server I get the exception above when running in Rails console, the same service class can be executed and runs correctly out of Rails. Same exception happens when running under MRI 1.9.3 Ruby and JRuby.
I've attached Gemfile.lock of both projects in the gist above
I was making some tests with the source code and I observed that the joyent/http-parser was tied in the 1.0 version and the current version is the 2.3.
The problem is that the joyent/http-parser repository's HEAD was detached (# HEAD detached at 62110ef
) and the extconf.rb tries to update the code from the git repository.
To fix it, I just removed the repository and added it again:
git submodule deinit ext/ruby_http_parser/vendor/http-parser
git rm ext/ruby_http_parser/vendor/http-parser
git submodule add https://github.com/joyent/http-parser.git ext/ruby_http_parser/vendor/http-parser
I ran the tests and everything worked fine, except the "HTTP::Parser should parse request: line folding in header value" item, but it is a little bit controversial, since the current http-parser version keeps the \t
in the header value and the old version remove s it.
A client sends this request:
CONNECT www.google.de: HTTP/1.0
Proxy-Authorization: Basic FAKEX2tleTphcGlfa2V5X3Rlc3RfdXNlcg==
Notice the colon after www.google.de:
. It works if there is a port number after the colon www.google.de:443
.
The message is Could not parse data entirely (22 != 100)
and the colon is the 22nd char.
I realise that the message above is probably malformed, but I'm not sure about that as I didn't find the relevant RFC yet. Still as we try to be robust in what data we accept, I could see this being accepted by http_parser.rb
. What do you think?
On Fedora 26
gem install http_parser
installs version 0.1.3
Trying to force doesn't work:
# gem install http_parser -v 0.6.0
ERROR: Could not find a valid gem 'http_parser' (= 0.6.0) in any repository
Moved from igrigorik/em-http-request#240
em-http-request does not work for http://hashbang.ca/.
The following script:
require 'em-http-request'
EM.run do
http = EM::HttpRequest.new('http://hashbang.ca/').head
http.callback do
puts "success"
EM.stop
end
http.errback do
puts "error: #{http.error}"
EM.stop
end
end
...returns this error.
error: Could not parse data entirely (389 != 645)
With telnet, I get the following response headers:
$ telnet hashbang.ca 80
Trying 178.79.155.139...
Connected to hashbang.ca.
Escape character is '^]'.
HEAD / HTTP/1.0
HTTP/1.1 200 OK
Server: nginx/1.4.1
Date: Tue, 23 Jul 2013 08:53:11 GMT
Content-Type: text/html; charset=UTF-8
Connection: close
Vary: Accept-Encoding
X-Powered-By: PHP/5.3.10-1ubuntu3.7
X-Pingback: http://hashbang.ca/xmlrpc.php
Expires: Tue, 23 Jul 2013 09:53:11 GMT
Cache-Control: max-age=3600
Strict-Transport-Security: max-age=31536000
Content-Security-Policy-Report-Only:
default-src 'self';
img-src *; style-src 'unsafe-inline' 'self';
script-src platform.twitter.com rum-static.pingdom.net 'unsafe-inline' 'self';
frame-src speakerdeck.com 'self';
report-uri http://csp.hashbang.ca;
Connection closed by foreign host.
...where Content-Security-Policy-Report-Only
looks odd. Could you give me any insights with the error?
FYI, browsers and net/http
works fine with the site.
A failing test case in em-http-request after update of http_parser.rb to 0.8.0 in Fedora found a possible unexpected behavior.
Considering the following HTTP response from the gem's test suite
HTTP/1.1 403 Forbidden
Content-Type: text/plain
Content-Length: 13
Access Denied
HTTP/1.1 403 Forbidden
Content-Type: text/plain
Content-Length: 13
Access Denied
Consider the following code which kind of mimics what the em-http-request is doing here with http_parser.rb. AFAICT, it is trying to prevent parsing of what I'd call a "double response".
data = "HTTP/1.1 403 Forbidden\nContent-Type: text/plain\nContent-Length: 15\n\nAccess Denieda\n\nHTTP/1.1 403 Forbidden\nContent-Type: text/plain\nContent-Length: 13\n\nAccess Denied"
parser = Http::Parser.new
received = true
parser.on_headers_complete= proc { |h|
if received
received = false
p h
else
parser.reset!
end
}
parser.on_message_complete = proc { p "Done" }
parser << data
Running the above code with http_parser.rb 0.8.0 I observe the following:
{"Content-Type"=>"text/plain", "Content-Length"=>"15"}
"Done"
"Done"
While parser got reset in the middle of previous parsing, it seems to continue to parse out the second request just fine.
Compare it to behavior of v0.6.0 that happily throws an exception:
{"Content-Type"=>"text/plain", "Content-Length"=>"13"}
"Access Denied"
"Done"
(irb):158:in `<<': Could not parse data entirely (151 != 164) (HTTP::Parser::Error)
<...snip...>
Is the v0.8.0 behavior now the expected one, or is it a bug of the new version?
Thanks for clarification.
$ ruby -v
ruby 2.4.1p111 (2017-03-22 revision 58053) [i386-mingw32]
$ gem -v
2.6.11
$ gem install http_parser.rb
ERROR: Error installing http_parser.rb:
ERROR: Failed to build gem native extension.
current directory: C:/Ruby24/lib/ruby/gems/2.4.0/gems/http_parser.rb-0.6.0/ext/ruby_http_parser
C:/Ruby24/bin/ruby.exe -r ./siteconf20180201-7684-tn7ypo.rb extconf.rb
creating Makefile
current directory: C:/Ruby24/lib/ruby/gems/2.4.0/gems/http_parser.rb-0.6.0/ext/ruby_http_parser
make "DESTDIR=" clean
current directory: C:/Ruby24/lib/ruby/gems/2.4.0/gems/http_parser.rb-0.6.0/ext/ruby_http_parser
make "DESTDIR="
generating ruby_http_parser-i386-mingw32.def
make: *** No rule to make target '/C/Ruby24/include/ruby-2.4.0/ruby.h', needed by 'ruby_http_parser.o'. Stop.
make failed, exit code 2
Gem files will remain installed in C:/Ruby24/lib/ruby/gems/2.4.0/gems/http_parser.rb-0.6.0 for inspection.
Results logged to C:/Ruby24/lib/ruby/gems/2.4.0/extensions/x86-mingw32/2.4.0/http_parser.rb-0.6.0/gem_make.out
Temporarily enhancing PATH for MSYS/MINGW...
Building native extensions. This could take a while...
While packaging http_parser.rb, ruby 1.9.1 tests are failing with
/usr/lib/ruby/vendor_ruby/json/common.rb:155:in `encode': "\xC3" on
US-ASCII (Encoding::InvalidByteSequenceError)
in pbuilder (a clean package building tool which defaults to LANG=C). Looking on the web I found
http://stackoverflow.com/questions/12130162/cucumber-fails-with-json-encodinginvalidbytesequenceerror
I have LANG=ml_IN as my default locale and dpkg-buildpackage works
(which uses my system locale). Also ruby 1.8 does not have this
problem.
an interesting discussion I found on this topic
http://www.ruby-forum.com/topic/136955
I think it is a bug in json library to depend on system locale. Any
ideas how to fix this?
I was thinking of setting up a UTF8 locale in pbuilder, but that
doesn't seem like the right approach.
You can run LANG=C rspec to reproduce this error.
$ LANG=C rspec
/usr/lib/ruby/vendor_ruby/json/common.rb:155:in `encode': "\xC3" on US-ASCII (Encoding::InvalidByteSequenceError)
from /usr/lib/ruby/vendor_ruby/json/common.rb:155:in `initialize'
from /usr/lib/ruby/vendor_ruby/json/common.rb:155:in `new'
from /usr/lib/ruby/vendor_ruby/json/common.rb:155:in `parse'
from /media/pravi/forge/debian/git/pkg-ruby-extras/ruby-http-parser.rb/spec/parser_spec.rb:286:in `block (2 levels) in <top (required)>'
from /media/pravi/forge/debian/git/pkg-ruby-extras/ruby-http-parser.rb/spec/parser_spec.rb:285:in `each'
from /media/pravi/forge/debian/git/pkg-ruby-extras/ruby-http-parser.rb/spec/parser_spec.rb:285:in `block in <top (required)>'
from /usr/lib/ruby/vendor_ruby/rspec/core/example_group.rb:242:in `module_eval'
from /usr/lib/ruby/vendor_ruby/rspec/core/example_group.rb:242:in `subclass'
from /usr/lib/ruby/vendor_ruby/rspec/core/example_group.rb:228:in `describe'
from /usr/lib/ruby/vendor_ruby/rspec/core/dsl.rb:18:in `describe'
from /media/pravi/forge/debian/git/pkg-ruby-extras/ruby-http-parser.rb/spec/parser_spec.rb:4:in `<top (required)>'
from /usr/lib/ruby/vendor_ruby/rspec/core/configuration.rb:819:in `load'
from /usr/lib/ruby/vendor_ruby/rspec/core/configuration.rb:819:in `block in load_spec_files'
from /usr/lib/ruby/vendor_ruby/rspec/core/configuration.rb:819:in `each'
from /usr/lib/ruby/vendor_ruby/rspec/core/configuration.rb:819:in `load_spec_files'
from /usr/lib/ruby/vendor_ruby/rspec/core/command_line.rb:22:in `run'
from /usr/lib/ruby/vendor_ruby/rspec/core/runner.rb:80:in `run'
from /usr/lib/ruby/vendor_ruby/rspec/core/runner.rb:17:in `block in autorun'
While using twitter-stream (which uses http_parser.rb) to consume Twitter's firehose, I often get HTTP::Parser::Error exceptions.
It seems I am not the only one since this Gist from @igrigorik underlines the issues perfectly while parsing a GET query to google.ca.
How to reproduce?
# test.rb:
require 'http/parser' # http_parser.rb
h = Http::Parser.new
h.on_headers_complete = proc {|h| p [:headers, h] }
h.on_body = proc {|b| p [:on_body, b] }
h.on_message_complete = proc { p [:complete] }
h << `curl -i www.google.ca`
When running this you'd get:
test.rb:8:in `<<': Could not parse data entirely (HTTP::Parser::Error) from test.rb:8:in `<main>'
HTH.
Hi. I've just installed jekyll on my machine and when doing gem install jekyll bundler
everything gets installed correctly except for the following message from your gem:
...
Parsing documentation for i18n-1.14.3
Installing ri documentation for i18n-1.14.3
Parsing documentation for http_parser.rb-0.8.0
unknown encoding name "chunked\r\n\r\n25" for ext/ruby_http_parser/vendor/http-parser-java/tools/parse_tests.rb, skipping
Installing ri documentation for http_parser.rb-0.8.0
Parsing documentation for eventmachine-1.2.7
Installing ri documentation for eventmachine-1.2.7
...
It would be nice to fix this message so the installation is done completely clean.
Thx!
It has been over six months since the last beta release. It looks like there are currently 12 open issues (not including this one). Which, if any, of these are blockers? What can I do to help push this release forward?
Please see the discussion here: https://github.com/tweetstream/tweetstream/pull/151/files#r7859255
ruby 2.5.2p104 (2018-10-18 revision 65133) [x86_64-darwin17]
gem 'rails', '~> 5.2.1'
macos 10.14.1
Homebrew 1.8.4
gem 'twitter', github: 'sferik/twitter', require: false
Fetching http_parser.rb 0.6.0
Installing http_parser.rb 0.6.0 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
current directory: /Users/svezhatinka/.rbenv/versions/2.5.2/lib/ruby/gems/2.5.0/gems/http_parser.rb-0.6.0/ext/ruby_http_parser
/Users/svezhatinka/.rbenv/versions/2.5.2/bin/ruby -r ./siteconf20181129-13283-1wwtham.rb extconf.rb
creating Makefile
current directory: /Users/svezhatinka/.rbenv/versions/2.5.2/lib/ruby/gems/2.5.0/gems/http_parser.rb-0.6.0/ext/ruby_http_parser
make "DESTDIR=" clean
xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at:
/Library/Developer/CommandLineTools/usr/bin/xcrun
current directory: /Users/svezhatinka/.rbenv/versions/2.5.2/lib/ruby/gems/2.5.0/gems/http_parser.rb-0.6.0/ext/ruby_http_parser
make "DESTDIR="
xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at:
/Library/Developer/CommandLineTools/usr/bin/xcrun
make failed, exit code 1
Gem files will remain installed in /Users/svezhatinka/.rbenv/versions/2.5.2/lib/ruby/gems/2.5.0/gems/http_parser.rb-0.6.0 for inspection.
Results logged to
/Users/svezhatinka/.rbenv/versions/2.5.2/lib/ruby/gems/2.5.0/extensions/x86_64-darwin-17/2.5.0-static/http_parser.rb-0.6.0/gem_make.out
An error occurred while installing http_parser.rb (0.6.0), and Bundler cannot continue.
Make sure that `gem install http_parser.rb -v '0.6.0' --source 'https://rubygems.org/'` succeeds before bundling.
In Gemfile:
twitter was resolved to 6.2.0, which depends on
http was resolved to 3.3.0, which depends on
http_parser.rb
There is an issue in the currently released gem with the Java encoding of upgrade data which has been fixed in master. Would it be possible to get a new gem pushed out for http_parser.rb?
After struggling with celluloid/reel#40 for some time, I switched to rubinius to test and the problem disappears. @tmm1 stepped into that issue on Reel, and the details are there. Figured I would refocus the issue to http_parser.rb specifically since it is not Reel related.
Looks like the upstream C parser fixed a bug recently in HTTP/2 upgrade advertisements that was causing on_body
to never be called. All that is needed to fix here is to pull a newer version of nodejs/http-parser. I have already tried this and it works.
(Found by way of em-http-request#333)
RubyGems.org doesn't report a license for your gem. This is because it is not specified in the gemspec of your last release.
via e.g.
spec.license = 'MIT'
# or
spec.licenses = ['MIT', 'GPL-2']
Including a license in your gemspec is an easy way for rubygems.org and other tools to check how your gem is licensed. As you can imagine, scanning your repository for a LICENSE file or parsing the README, and then attempting to identify the license or licenses is much more difficult and more error prone. So, even for projects that already specify a license, including a license in your gemspec is a good practice. See, for example, how rubygems.org uses the gemspec to display the rails gem license.
There is even a License Finder gem to help companies/individuals ensure all gems they use meet their licensing needs. This tool depends on license information being available in the gemspec. This is an important enough issue that even Bundler now generates gems with a default 'MIT' license.
I hope you'll consider specifying a license in your gemspec. If not, please just close the issue with a nice message. In either case, I'll follow up. Thanks for your time!
Appendix:
If you need help choosing a license (sorry, I haven't checked your readme or looked for a license file), GitHub has created a license picker tool. Code without a license specified defaults to 'All rights reserved'-- denying others all rights to use of the code.
Here's a list of the license names I've found and their frequencies
p.s. In case you're wondering how I found you and why I made this issue, it's because I'm collecting stats on gems (I was originally looking for download data) and decided to collect license metadata,too, and make issues for gemspecs not specifying a license as a public service :). See the previous link or my blog post about this project for more information.
I discovered this while investigating faye/faye-websocket-ruby#18.
The following script constructs a draft-76 WebSocket request with 8 random bytes of upgrade data in the body after the headers. It then uses Http::Parser
to process it and spit out the expected and parsed upgrade data bytes:
require 'http/parser'
upgrade_data = (1..8).map { rand 255 }
bytes = [ 71, 69, 84, 32, 47, 32, 72, 84, 84, 80, 47, 49, 46, 49, 13, 10, 85,
112, 103, 114, 97, 100, 101, 58, 32, 87, 101, 98, 83, 111, 99, 107,
101, 116, 13, 10, 67, 111, 110, 110, 101, 99, 116, 105, 111, 110, 58,
32, 85, 112, 103, 114, 97, 100, 101, 13, 10, 72, 111, 115, 116, 58,
32, 108, 111, 99, 97, 108, 104, 111, 115, 116, 58, 55, 48, 48, 49,
13, 10, 79, 114, 105, 103, 105, 110, 58, 32, 104, 116, 116, 112, 58,
47, 47, 108, 111, 99, 97, 108, 104, 111, 115, 116, 58, 55, 48, 48,
49, 13, 10, 83, 101, 99, 45, 87, 101, 98, 83, 111, 99, 107, 101, 116,
45, 75, 101, 121, 49, 58, 32, 49, 57, 32, 111, 49, 55, 32, 54, 50,
32, 52, 32, 53, 50, 13, 10, 83, 101, 99, 45, 87, 101, 98, 83, 111,
99, 107, 101, 116, 45, 75, 101, 121, 50, 58, 32, 79, 52, 32, 48, 97,
103, 39, 53, 121, 57, 32, 32, 72, 32, 54, 60, 32, 54, 101, 32, 57,
49, 50, 13, 10, 13, 10] +
upgrade_data
string = bytes.pack('C*')
parser = Http::Parser.new
parser << string
puts 'Expected bytes:'
p upgrade_data
puts 'Actual bytes:'
p parser.upgrade_data.bytes.to_a
On MRI 1.9.3-p392, the expected and actual results always match. But on JRuby 1.7.2, the actual output bytes are different from the expected ones, and parser.upgrade_data
often contains more than the intended 8 bytes.
I'm not sure if I'm using it wrong or if this is a bug in Http::Parser
.
Steps:
~/http parser/
)http_parser.rb
to a Gemfile
:source 'https://rubygems.org'
gem 'http_parser.rb'
bundle install --path _vendor
What happens:
Fetching gem metadata from https://rubygems.org/.
Fetching version metadata from https://rubygems.org/
Resolving dependencies...
Installing http_parser.rb 0.6.0 with native extensions
Using bundler 1.13.2
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
current directory: /Users/ale/Desktop/tmp/http parser/_vendor/gems/http_parser.rb-0.6.0/ext/ruby_http_parser
/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby -r ./siteconf20161005-24321-171301n.rb extconf.rb
creating Makefile
current directory: /Users/ale/Desktop/tmp/http parser/_vendor/gems/http_parser.rb-0.6.0/ext/ruby_http_parser
make "DESTDIR=" clean
current directory: /Users/ale/Desktop/tmp/http parser/_vendor/gems/http_parser.rb-0.6.0/ext/ruby_http_parser
make "DESTDIR="
compiling ruby_http_parser.c
clang: error: no such file or directory: 'parser/_vendor/gems/http_parser.rb-0.6.0/ext/ruby_http_parser'
make: *** [ruby_http_parser.o] Error 1
make failed, exit code 2
Gem files will remain installed in /Users/ale/Desktop/tmp/http parser/_vendor/gems/http_parser.rb-0.6.0 for
inspection.
Results logged to /Users/ale/Desktop/tmp/http
parser/_vendor/extensions/universal-darwin-16/2.0.0/http_parser.rb-0.6.0/gem_make.out
An error occurred while installing http_parser.rb (0.6.0), and Bundler cannot continue.
Make sure that `gem install http_parser.rb -v '0.6.0'` succeeds before bundling.
Renaming the folder to http_parser
fixes the issue.
I think it is the path format issue:
Not "/D/Software/msys64/ucrt64/include/ruby-3.1.0/"
But "D:/Software/msys64/ucrt64/include/ruby-3.1.0/"
$ gem install jekyll
Building native extensions. This could take a while...
ERROR: Error installing jekyll:
ERROR: Failed to build gem native extension.
current directory: D:/Software/msys64/ucrt64/lib/ruby/gems/3.1.0/gems/http_parser.rb-0.8.0/ext/ruby_http_parser
D:/Software/msys64/ucrt64/bin/ruby.exe extconf.rb
creating Makefile
current directory: D:/Software/msys64/ucrt64/lib/ruby/gems/3.1.0/gems/http_parser.rb-0.8.0/ext/ruby_http_parser
make DESTDIR\= sitearchdir\=./.gem.20230827-13144-cmqhxv sitelibdir\=./.gem.20230827-13144-cmqhxv clean
current directory: D:/Software/msys64/ucrt64/lib/ruby/gems/3.1.0/gems/http_parser.rb-0.8.0/ext/ruby_http_parser
make DESTDIR\= sitearchdir\=./.gem.20230827-13144-cmqhxv sitelibdir\=./.gem.20230827-13144-cmqhxv
generating ruby_http_parser-x64-mingw-ucrt.def
make: *** No rule to make target '/D/Software/msys64/ucrt64/include/ruby-3.1.0/ruby.h', needed by 'ruby_http_parser.o'. Stop.
make failed, exit code 2
Gem files will remain installed in D:/Software/msys64/ucrt64/lib/ruby/gems/3.1.0/gems/http_parser.rb-0.8.0 for inspection.
Results logged to D:/Software/msys64/ucrt64/lib/ruby/gems/3.1.0/extensions/x64-mingw-ucrt/3.1.0/http_parser.rb-0.8.0/gem_make.out
There are several security issues in the dependencies and they should be updated:
usr/lib/ruby/gems/2.5.0/gems/http_parser.rb-0.6.0/Gemfile.lock
==============================================================
Total: 8 (UNKNOWN: 1, LOW: 0, MEDIUM: 5, HIGH: 0, CRITICAL: 2)
+-----------+------------------+----------+-------------------+------------------------------+--------------------------------+
| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE |
+-----------+------------------+----------+-------------------+------------------------------+--------------------------------+
| ffi | CVE-2018-1000201 | MEDIUM | 1.0.11 | >= 1.9.24 | ruby-ffi DDL loading issue on |
| | | | | | Windows OS |
+ + + +-------------------+ + +
| | | | 1.0.11-java | | |
| | | | | | |
+-----------+------------------+----------+-------------------+------------------------------+--------------------------------+
| json | CVE-2013-0269 | CRITICAL | 1.8.0-java | ~> 1.5.5, ~> 1.6.8, >= 1.7.7 | rubygem-json: Denial of |
| | | | | | Service and SQL Injection |
+ +------------------+----------+-------------------+------------------------------+--------------------------------+
| | CVE-2020-10663 | MEDIUM | 1.8.0 | >= 2.3.0 | rubygem-json: Unsafe Object |
| | | | | | Creation Vulnerability in JSON |
+ + + +-------------------+ + +
| | | | 1.8.0-java | | |
| | | | | | |
+ +------------------+----------+ +------------------------------+--------------------------------+
| | OSVDB-101157 | UNKNOWN | | >= 1.1.0 | json Gem for Ruby Data |
| | | | | | Handling Stack Buffer Overflow |
+-----------+------------------+----------+-------------------+------------------------------+--------------------------------+
| rake | CVE-2020-8130 | CRITICAL | 0.9.2 | >= 12.3.3 | rake: OS Command Injection via |
| | | | | | egrep in Rake::FileList |
+-----------+------------------+----------+-------------------+------------------------------+--------------------------------+
| yajl-ruby | CVE-2017-16516 | MEDIUM | 1.1.0 | >= 1.3.1 | rubygem-yajl-ruby: |
| | | | | | Yajl::Parser.new.parse |
| | | | | | incorrect parsing |
+-----------+------------------+----------+-------------------+------------------------------+--------------------------------+
The current implementation of the state machine doesn't handle "whitespace" in the URL path properly.
According to man 3 isspace:
isspace() checks for white-space characters. In the "C" and "POSIX" locales, these are: space, form-feed ('\f'), newline ('\n'), carriage return ('\r'), horizontal tab ('\t'), and vertical tab ('\v').
Any path with a form-feed or either tab will fail the assertion on ryah_http_parser.c:420. I found this error when a client's pen tester hit a proxy we had created with goliath which uses 0.6.0.beta.2 of your ruby gem.
Also here are some patches that will cause your tests to fail. 1st the submodule:
diff --git a/test.c b/test.c index 184ba24..d2af3ce 100644 --- a/test.c +++ b/test.c @@ -178,6 +178,25 @@ const struct message requests[] = ,.body= "" } · +#define WHITESPACE_IN_URI_PATH 3 +, {.name= "whitespace in path" + ,.type= HTTP_REQUEST + ,.raw= "GET /forums/1/topics\f/2375?page=1#posts-17408 HTTP/1.1\r\n" + "\r\n" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_GET + ,.query_string= "page=1" + ,.fragment= "posts-17408" + ,.request_path= "/forums/1/topics/2375" + /* XXX request url does include fragment? */ + ,.request_url= "/forums/1/topics/2375?page=1#posts-17408" + ,.num_headers= 0 + ,.body= "" + } + #define GET_NO_HEADERS_NO_BODY 4 , {.name= "get no headers no body" ,.type= HTTP_REQUEST
And the main repo
diff --git a/spec/support/requests.json b/spec/support/requests.json index dbb6e98..04d5ae7 100644 --- a/spec/support/requests.json +++ b/spec/support/requests.json @@ -86,6 +86,23 @@ "strict": true }, { + "name": "whitespace in path", + "type": "HTTP_REQUEST", + "raw": "GET /forums/1/topics\f/2375?page=1#posts-17408 HTTP/1.1\r\n\r\n", + "should_keep_alive": true, + "message_complete_on_eof": false, + "http_major": 1, + "http_minor": 1, + "method": "GET", + "query_string": "page=1", + "fragment": "posts-17408", + "request_path": "/forums/1/topics\f/2375", + "request_url": "/forums/1/topics\f/2375?page=1#posts-17408", + "num_headers": 0, + "body": "", + "strict": true + }, + { "name": "get no headers no body", "type": "HTTP_REQUEST", "raw": "GET /get_no_headers_no_body/world HTTP/1.1\r\n\r\n", @@ -609,4 +626,4 @@ }, "body": "" } -] \ No newline at end of file +]
Steps to reproduce: Parse any HTTP response (ex. HTTP/1.1 200 OK)
How can one access to the reason phrase of the parsed message?
OSX embeded cruby require 'http/parser'
will report this bug.
Linux worked well.
ruby_init();
// must: or read_nonblock, write_nonblock is none
char* options[] = { "-v", "-eputs 'Hello, world!'" };
void* node = ruby_options(2, options);
VALUE script = rb_str_new_cstr("./src/ruby/app.rb");
rb_load(script, 0);
app.rb
require 'http/parser'
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.