8

heroku に奇妙なバグがあります。それを再現するには、リクエスト本文にUTF-8文字を含む大きな(数KB以上の)HTTPS POSTを作成する必要があります。次に例を示します。

require "net/https"
require "uri"

#Accutally I've ecountered this bug while posting to another server
url = URI.parse("https://api.heroku.com/myapps")

#It's Ukrainian 'oiced velar plosive G' letter
payload = "ґ"*10000
request = Net::HTTP::Post.new(url.path)
request.body = payload
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.read_timeout = 500
http.start {|http| http.request request }

このようなスクリプトをローカル マシンの irb で実行すると、次のようになります。

#<Net::HTTPUnauthorized 401 Unauthorized readbody=true> 

...これは予想どおりですが、heroku cedar で「heroku console」で実行すると、約 60 秒で次のようになります。

EOFError: end of file reached
    from /usr/local/lib/ruby/1.9.1/openssl/buffering.rb:145:in `sysread_nonblock'
    from /usr/local/lib/ruby/1.9.1/openssl/buffering.rb:145:in `read_nonblock'
    from /usr/local/lib/ruby/1.9.1/net/protocol.rb:135:in `rbuf_fill'
    from /usr/local/lib/ruby/1.9.1/net/protocol.rb:116:in `readuntil'
    from /usr/local/lib/ruby/1.9.1/net/protocol.rb:126:in `readline'
    from /usr/local/lib/ruby/1.9.1/net/http.rb:2219:in `read_status_line'
    from /usr/local/lib/ruby/1.9.1/net/http.rb:2208:in `read_new'
    from /usr/local/lib/ruby/1.9.1/net/http.rb:1191:in `transport_request'
    from /usr/local/lib/ruby/1.9.1/net/http.rb:1177:in `request'
    from (irb):32:in `block in irb_binding'
    from /usr/local/lib/ruby/1.9.1/net/http.rb:627:in `start'
    from (irb):32
    from /app/vendor/bundle/ruby/1.9.1/gems/railties-3.2.7/lib/rails/commands/console.rb:47:in `start'
    from /app/vendor/bundle/ruby/1.9.1/gems/railties-3.2.7/lib/rails/commands/console.rb:8:in `start'
    from /app/vendor/bundle/ruby/1.9.1/gems/railties-3.2.7/lib/rails/commands.rb:41:in `<top (required)>'

どうすればいいですか?

4

2 に答える 2

3

デフォルトの Cedar の ruby​​ は 1.9.2 であるため、 ruby​​ バージョンをGemfileに追加する必要がありました (これには、SSL 経由で UTF-8 文字列を渡すバグがあります)。

source 'https://rubygems.org'
ruby "1.9.3"

gem 'rails', '3.2.7'
gem 'pg'
...
于 2012-09-12T14:47:12.563 に答える
2

私は、これはうまくいくはずだと思います:

require "net/https"
require "uri"

url = URI.parse("https://api.heroku.com/myapps")
#It's Ukrainian letter 'soft-G'
payload = "ґ"*10000
request = Net::HTTP::Post.new(url.path)
request.basic_auth 'youremail', 'yourpassword'
request.body = URI.encode(payload)
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.read_timeout = 500
http.start {|http| http.request request }
于 2012-09-12T14:08:54.523 に答える