35

URL を開くために open-uri を使用しています。

resp = open("http://sub_domain.domain.com")

アンダースコアが含まれている場合、エラーが発生します。

URI::InvalidURIError: スキーム http はレジストリ部分を受け入れません: sub_domain.domain.com (または不正なホスト名?)

これは、RFC によると URL に文字と数字のみを含めることができるためであることを理解しています。回避策はありますか?

4

9 に答える 9

20

これは URI のバグのようで、uri-open、HTTParty、およびその他の多くの gem が URI.parse を利用しています。

回避策は次のとおりです。

require 'net/http'
require 'open-uri'

def hopen(url)
  begin
    open(url)
  rescue URI::InvalidURIError
    host = url.match(".+\:\/\/([^\/]+)")[1]
    path = url.partition(host)[2] || "/"
    Net::HTTP.get host, path
  end
end

resp = hopen("http://dear_raed.blogspot.com/2009_01_01_archive.html")
于 2011-03-06T08:49:50.253 に答える
14

私のレールアプリのこの初期化子は、少なくとも URI.parse を機能させるようです:

# config/initializers/uri_underscore.rb
class URI::Generic
  def initialize_with_registry_check(scheme,
                 userinfo, host, port, registry,
                 path, opaque,
                 query,
                 fragment,
                 parser = DEFAULT_PARSER,
                 arg_check = false)
    if %w(http https).include?(scheme) && host.nil? && registry =~ /_/
      initialize_without_registry_check(scheme, userinfo, registry, port, nil, path, opaque, query, fragment, parser, arg_check)
    else
      initialize_without_registry_check(scheme, userinfo, host, port, registry, path, opaque, query, fragment, parser, arg_check)
    end
  end
  alias_method_chain :initialize, :registry_check
end
于 2013-02-11T15:51:58.833 に答える
3

そのようなドメイン名にアンダースコアを含めることはできません。これは DNS 標準の一部です。ダッシュ ( -) を使用するつもりでしたか?

open-uri がエラーをスローしなかったとしても、そのようなコマンドは無意味です。なんで?そのようなドメイン名を解決できる方法がないためです。unknown hostせいぜい、エラーが発生するでしょう。を含むドメイン名を登録する方法はありません_。独自のプライベート DNS サーバーを実行していても、_. ルールを曲げて許可することはできますが (DNS サーバー ソフトウェアを変更することにより)、オペレーティング システムの DNS リゾルバーはそれをサポートしません。また、ルーターの DNS ソフトウェアもサポートしません。

_解決策: DNS 名に aを使用しないでください。どこでも機能せず、仕様に反しています

于 2011-03-06T05:17:12.237 に答える
2

gem update / gem install などを使用しようとしているときに同じエラーが発生したため、代わりに IP アドレスを使用しましたが、現在は問題ありません。

于 2013-10-23T13:11:39.327 に答える
0

libcurl をラップするだけの Curb gem: https://github.com/taf2/curbを使用することをお勧めします。以下は、自動的にリダイレクトに従い、応答コードと応答本文を出力する簡単な例です。

rsp = Curl::Easy.http_get(url){|curl| curl.follow_location = true; curl.max_redirects=10;}
puts rsp.response_code
puts rsp.body_str

私は通常、ルビーの URI クラスを避けます。これは、Web が野生の西部であることを知っているように、仕様に厳しすぎるためです:) Curl/curb は、私が投げたすべての URL をチャンプのように処理します。

于 2012-05-18T14:34:17.363 に答える