Issue #8241 has been reported by neocoin (Sangmin Ryu).

----------------------------------------
Bug #8241: If uri host-part has underscore ( '_' ), 'URI#parse' raise 'URI::InvalidURIError'
https://bugs.ruby-lang.org/issues/8241

Author: neocoin (Sangmin Ryu)
Status: Open
Priority: Normal
Assignee: akira (akira yamada)
Category: core
Target version: 
ruby -v: ruby 2.0.0p0 (2013-02-24 revision 39474) [x86_64-darwin11.4.2]


First of all, 
I say 'I am sorry', if this issue making activity is rude. 
I don't know, where do I put this simple and critical issue. 
This problem was found a long time ago (1 or 2 years ). 
But problem is very clear and solution very simple.
So I wait just long time with monkey patch. 


If uri host-part has underscore ( '_' ), 'URI#parse' raise 'URI::InvalidURIError'

ex) 
=begin
>require 'uri'
>URI.parse 'http://test_strin.helo.com'
URI::InvalidURIError: the scheme http does not accept registry part: test_strin.helo.com (or bad hostname?)
from ... /.rbenv/versions/1.9.3-p125/lib/ruby/1.9.1/uri/generic.rb:213:in `initialize'
>
>
> e=URI.parse('http://test_string.hello.com') rescue $!
=> #<URI::InvalidURIError: the scheme http does not accept registry part: test_string.hello.com (or bad hostname?)>
> puts e.backtrace
.../.rbenv/versions/2.0.0-p0/lib/ruby/2.0.0/uri/generic.rb:214:in `initialize'
.../.rbenv/versions/2.0.0-p0/lib/ruby/2.0.0/uri/http.rb:84:in `initialize'
.../.rbenv/versions/2.0.0-p0/lib/ruby/2.0.0/uri/common.rb:214:in `new'
.../.rbenv/versions/2.0.0-p0/lib/ruby/2.0.0/uri/common.rb:214:in `parse'
.../.rbenv/versions/2.0.0-p0/lib/ruby/2.0.0/uri/common.rb:747:in `parse'

vs

>URI.parse('http://teststring.hello.com') 
>#<URI::HTTP:0x007fbf31c1a078 URL:http://teststring.hello.com>
=end

This problem is made by hostname regex pattern of 'URI#split ' in uri/common.rb

https://bugs.ruby-lang.org/projects/ruby-trunk/repository/entry/lib/uri/common.rb#L368
( https://github.com/ruby/ruby/blob/trunk/lib/uri/common.rb#L368 )

=begin
[26] pry(main)> URI.split('http://teststring.hello.com')
=> ["http", nil, "teststring.hello.com", nil, nil, "", nil, nil, nil]     // normal

[27] pry(main)> URI.split('http://test_string.hello.com')
=> ["http", nil, nil, nil, "test_string.hello.com", "", nil, nil, nil]    // wrong

source position. 
https://bugs.ruby-lang.org/projects/ruby-trunk/repository/entry/lib/uri/common.rb#L368
( https://github.com/ruby/ruby/blob/trunk/lib/uri/common.rb#L368 )

=begin
      # hostname      = *( domainlabel "." ) toplabel [ "." ]
      # reg-name      = *( unreserved / pct-encoded / sub-delims ) # RFC3986
      unless hostname
        ret[:HOSTNAME] = hostname = "(?:[a-zA-Z0-9\\-.]|%\\h\\h)+"
      end
=end

Through you could check source comment, 'reg-name'  in rfc3986 could be 'unreserved / pct-encoded / sub-delims )'

And 'unreserved' definition in rfc3986 ( http://tools.ietf.org/html/rfc3986#section-2.3 )

> unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"

But hostname regex pattern has just '-' and '.' except '_' and '~'.

Please, check rfc3986 and add hostname pattern for reg-name like below.

=begin
        ret[:HOSTNAME] = hostname = "(?:[a-zA-Z0-9\\-._~]|%\\h\\h)+"
=end




-- 
http://bugs.ruby-lang.org/