HTTP doesn't work. A bug?

Hi all,

downloading a larger file, I encounter this error message:

/usr/lib/ruby/1.8/net/protocol.rb:197:in `sysread': End of file reached (EOFError)
        from /usr/lib/ruby/1.8/net/protocol.rb:197:in `rbuf_fill'
        from /usr/lib/ruby/1.8/net/protocol.rb:196:in `timeout'
        from /usr/lib/ruby/1.8/timeout.rb:55:in `timeout'
        from /usr/lib/ruby/1.8/net/protocol.rb:196:in `rbuf_fill'
        from /usr/lib/ruby/1.8/net/protocol.rb:160:in `readuntil'
        from /usr/lib/ruby/1.8/net/protocol.rb:171:in `readline'
        from /usr/lib/ruby/1.8/net/http.rb:1554:in `read_status_line'
        from /usr/lib/ruby/1.8/net/http.rb:1538:in `read_new'
        from /usr/lib/ruby/1.8/net/http.rb:833:in `request'
        from /usr/lib/ruby/1.8/net/http.rb:734:in `request_get'
        from ./mautdaten.rb:154:in `getfile'
        from ./mautdaten.rb:252:in `loadnewest'
        from ./mautdaten.rb:354

The program below does a straight download without any
errors, but when the same code is integrated in a larger
program, I get the error message. Sorry, I didn't manage to
find out where the message disappears when shortening the
code.

The error happens only with a download through a modem. In
my small home network everything works properly. I use
Apache 1.3.26. Outside, I tried to load from 1.3.29 and 2.0
versions.

What do I have to to?

Bertram

···

----------------------------------------
#!/usr/bin/env ruby

class StopDownload < Exception
end

class StoreLoaded

  def initialize( name, rfcdate, length)
    require 'time'
    lm = Time.httpdate rfcdate
    if File.exist? name then
      if lm <= File.ctime( name) and length == File.size( name) then
        raise StopDownload
      end
      File.delete name
    end
    @fileobj = File.new name, 'w'
    @fileobj.chmod 0444
  end

  def write( b)
    @fileobj.write b
  end

  def << ( buf)
    write buf
    self
  end

  def flush
  end

  def close
    @fileobj.close
    freeze
  end
end

class HTTPLoad

  def initialize host
    require 'net/http'
    @conn = Net::HTTP.new host
  end

  def getfile( path, cls)
    localfile = nil
    @conn.request_get path do |resp|
      if resp.code.to_i / 100 != 2 then
        raise Error, "`%s\': %03d, %s" % [path, resp.code, resp.msg]
      end
      begin
        localfile = cls.new 'localfile',
                      resp[ 'Last-Modified'], resp.content_length
        resp.read_body do |buf|
          localfile << buf
        end
        localfile.close
      rescue StopDownload
      end
    end
    localfile
  end

end

if __FILE__ == $0
  # The first site works always, the second only in this
  # shortened example.
  [['homer', '/another/maut/maut_55a.csv'],
   ['www.mauttabelle.de', '/maut_55a.csv']].each do |host,path|
    c = HTTPLoad.new( host)
    c.getfile path, StoreLoaded
  end
end
----------------------------------------

--
Bertram Scharpf
Stuttgart, Deutschland/Germany
http://www.bertram-scharpf.de

Hi,

Hi all,

downloading a larger file, I encounter this error message:

/usr/lib/ruby/1.8/net/protocol.rb:197:in `sysread': End of file reached (EOFError)

The error happens only with a download through a modem. In
my small home network everything works properly. I use
Apache 1.3.26. Outside, I tried to load from 1.3.29 and 2.0
versions.

I examined the problem thoroughly and now, I can reproduce
it reliably.

What I have to do is starting several instances of

    wget -o /dev/null -O /dev/null http://www.ruby-doc.org/downloads/ruby-doc-bundle.tar.gz

Then, the program below dies when loading the first file the
second time.

I tried it with a maximum of debugging output, I even hacked
the interpreter to get some more. I diff'ed the results
against those of the run without the parallel downloads.
I didn't find any hint.

Of course, the program works when I omit the `conn.start'
statement, but I think it should get along with it.

The problem seems to be compiler-independent (GNU C 2.95
and 3.3).

Could anyone who knows more about socket connections please
have a look at the problem. I will provide any further
information.

Bertram

···

Am Donnerstag, 30. Dez 2004, 08:43:52 +0900 schrieb Bertram Scharpf:

------------------------------

require 'net/http'

s, t = [ 'www.rayninfo.co.uk', 'www.ruby-doc.org']
f, g = [ '/vimtips.html', '/docs/CLR-FAQ/ruby_newsgroup_faq.txt']

c, d = [ s, t].collect { |host| Net::HTTP.new host }

[ c, d].each { |conn| conn.start }

100.times do |n|
  [ [c,f], [d,g]].each do |conn,file|
    conn.request_get file do |resp|
      resp.read_body do |buf|
      end
    end
  end
end

--
Bertram Scharpf
Stuttgart, Deutschland/Germany
http://www.bertram-scharpf.de