[#4766] Wiki — "Glen Stampoultzis" <trinexus@...>

21 messages 2000/09/04
[#4768] RE: Wiki — "NAKAMURA, Hiroshi" <nahi@...> 2000/09/04

Hi, Glen,

[#4783] Re: Wiki — Masatoshi SEKI <m_seki@...> 2000/09/04

[#4785] Re: Wiki — "NAKAMURA, Hiroshi" <nakahiro@...> 2000/09/05

Howdy,

[#4883] Re-binding a block — Dave Thomas <Dave@...>

16 messages 2000/09/12

[#4930] Perl 6 rumblings -- RFC 225 (v1) Data: Superpositions — Conrad Schneiker <schneik@...>

Hi,

11 messages 2000/09/15

[#4936] Ruby Book Eng. translation editor's questions — Jon Babcock <jon@...>

20 messages 2000/09/16

[#5045] Proposal: Add constants to Math — Robert Feldt <feldt@...>

15 messages 2000/09/21

[#5077] Crazy idea? infix method calls — hal9000@...

This is a generalization of the "in" operator idea which I

17 messages 2000/09/22

[#5157] Compile Problem with 1.6.1 — Scott Billings <aerogems@...>

When I try to compile Ruby 1.6.1, I get the following error:

15 messages 2000/09/27

[ruby-talk:5042] Re: Having problems with Net::HTTP::do_finish

From: Minero Aoki <aamine@...>
Date: 2000-09-21 07:13:26 UTC
List: ruby-talk #5042
This bug is resolved now.
Attaching patch may help. (a patch for 1.6.0's http.rb)

Minero Aoki

Index: http.rb
===================================================================
RCS file: /home/cvs/ruby/lib/net/http.rb,v
retrieving revision 1.27
retrieving revision 1.30
diff -u -r1.27 -r1.30
--- http.rb	2000/08/16 19:26:07	1.27
+++ http.rb	2000/09/21 06:58:01	1.30
@@ -1,6 +1,6 @@
 =begin
 
-= net/http.rb version 1.1.28
+= net/http.rb version 1.1.29
 
 maintained by Minero Aoki <aamine@dp.u-netsurf.ne.jp>
 This file is derived from "http-access.rb".
@@ -9,7 +9,11 @@
 You can distribute/modify this program under
 the terms of the Ruby Distribute License.
 
+Japanese version of this document is in "net" full package.
+You can get it from RAA
+(Ruby Application Archive: http://www.ruby-lang.org/en/raa.html).
 
+
 = class HTTP
 
 == Class Methods
@@ -33,7 +37,7 @@
 : start {|http| .... }
   creates a new Net::HTTP object and starts HTTP session.
 
-  When this method is called as iterator, gives HTTP object to block
+  When this method is called with block, gives HTTP object to block
   and close HTTP session after block call finished.
 
 : get( path, header = nil, dest = '' )
@@ -46,22 +50,21 @@
     # example
     response, body = http.get( '/index.html' )
 
-  If called as iterator, give a part String of entity body.
+  If called with block, give a part String of entity body.
 
   Note:
   If status is not 2xx(success), ProtocolError exception is
-  raised. At that time, you can get Response object from 
+  raised. At that time, you can get HTTPResponse object from 
   execption object. (same in head/post)
 
     # example
     begin
-      response, body = http.get(...)
+      response, body = http.get( '/index.html' )
     rescue Net::ProtoRetriableError
       response = $!.data
       ...
     end
 
-
 : head( path, header = nil )
   get only header from "path" on connecting host.
   "header" is a Hash like { 'Accept' => '*/*', ... }.
@@ -81,45 +84,75 @@
   "header" must be a Hash like { 'Accept' => '*/*', ... }.
   This method returns Net::HTTPResponse object and "dest".
 
-  If called as iterator, gives a part String of entity body.
+  If called with block, gives a part String of entity body.
 
-: get2( path, header = nil ) {|adapter| .... }
+: get2( path, header = nil )
+: get2( path, header = nil ) {|recv| .... }
   send GET request for "path".
   "header" must be a Hash like { 'Accept' => '*/*', ... }.
-  This method gives HTTPReadAdapter object to block.
+  If this method is called with block, one gives
+  a HTTPResponseReceiver object to block.
 
-    ex.
-    
-    http.get2( '/index.html' ) do |f|
-      # f is a HTTPReadAdapter object
-      f.header
-      f.body
+    # example
+    http.get2( '/index.html' ) do |recv|
+      # "recv" is a HTTPResponseReceiver object
+      recv.header
+      recv.body
+    end
+
+    # another way
+    response = http.get2( '/index.html' )
+    response['content-type']
+    response.body
+
+    # this is wrong
+    http.get2( '/index.html' ) do |recv|
+      print recv.header.body   # body is not read yet!!!
+    end
+
+    # but this is ok
+    http.get2( '/index.html' ) do |recv|
+      recv.body                # read body and set recv.header.body
+      print recv.header.body   # ref
     end
 
 : head2( path, header = nil )
+: head2( path, header = nil ) {|recv| .... }
   send HEAD request for "path".
   "header" must be a Hash like { 'Accept' => '*/*', ... }.
   The difference between "head" method is that
   "head2" does not raise exceptions.
 
-    ex.
-    
-    http.head2( '/index.html' ) do |f|
-      f.header
+  If this method is called with block, one gives
+  a HTTPResponseReceiver object to block.
+
+    # example
+    response = http.head2( '/index.html' )
+
+    # another way
+    http.head2( '/index.html' ) do |recv|
+      recv.response
     end
 
-: post2( path, data, header = nil ) {|adapter| .... }
+: post2( path, data, header = nil )
+: post2( path, data, header = nil ) {|recv| .... }
   post "data"(must be String now) to "path".
   "header" must be a Hash like { 'Accept' => '*/*', ... }.
-  This method gives HTTPReadAdapter object to block.
+  If this method is called with block, one gives
+  a HTTPResponseReceiver object to block.
 
-    ex.
-    
-    http.post2( '/index.html', 'data data data...' ) do |adapter|
-      adapter.header
-      adapter.body
+    # example
+    http.post2( '/anycgi.rb', 'data data data...' ) do |recv|
+      # "recv" is a HTTPResponseReceiver object
+      recv.header
+      recv.body
     end
 
+    # another way
+    response = http.post2( '/anycgi.rb', 'important data' )
+    response['content-type']
+    response.body
+
 
 = class HTTPResponse
 
@@ -151,8 +184,9 @@
 
 : message
   HTTP result message. For example, 'Not Found'
+
 
-= class HTTPReadAdapter
+= class HTTPResponseReceiver
 
 == Methods
 
@@ -165,8 +199,8 @@
   entity body. A body is written to "dest" using "<<" method.
 
 : body {|str| ... }
-  get entity body by using iterator.
-  If this method is called twice, block is not called and
+  gets entity body with block.
+  If this method is called twice, block is not executed and
   returns first "dest".
 
 
@@ -283,8 +317,9 @@
     end
 
     def get2( path, u_header = nil, &block )
-      connecting( u_header, block ) {|uh|
+      connecting( u_header ) {|uh|
         @command.get edit_path(path), uh
+        receive true, block
       }
     end
 
@@ -295,10 +330,10 @@
       resp
     end
 
-    def head2( path, u_header = nil )
-      connecting( u_header, nil ) {|uh|
+    def head2( path, u_header = nil, &block )
+      connecting( u_header ) {|uh|
         @command.head edit_path(path), uh
-        @command.get_response_no_body
+        receive false, block
       }
     end
 
@@ -311,8 +346,9 @@
     end
 
     def post2( path, data, u_header = nil, &block )
-      connecting( u_header, block ) {|uh|
+      connecting( u_header ) {|uh|
         @command.post edit_path(path), uh, data
+        receive true, block
       }
     end
 
@@ -325,8 +361,9 @@
     end
 
     def put2( path, src, u_header = nil, &block )
-      connecting( u_header, block ) {|uh|
+      connecting( u_header ) {|uh|
         @command.put path, uh, src
+        receive true, block
       }
     end
 
@@ -334,14 +371,7 @@
     private
 
 
-    # called when connecting
-    def do_finish
-      unless @socket.closed? then
-        head2 '/', { 'Connection' => 'close' }
-      end
-    end
-
-    def connecting( u_header, ublock )
+    def connecting( u_header )
       u_header = procheader( u_header )
       if not @socket then
         u_header['Connection'] = 'close'
@@ -351,12 +381,7 @@
       end
 
       resp = yield( u_header )
-      if ublock then
-        adapter = HTTPReadAdapter.new( @command )
-        ublock.call adapter
-        resp = adapter.off
-      end
-      
+
       unless keep_alive? u_header, resp then
         @socket.close
       end
@@ -396,22 +421,37 @@
       end
     end
 
+
+    def receive( body_exist, block )
+      recv = HTTPResponseReceiver.new( @command, body_exist )
+      block.call recv if block
+      recv.terminate
+      recv.header
+    end
+
+
+    # called when connecting
+    def do_finish
+      unless @socket.closed? then
+        head2 '/', { 'Connection' => 'close' }
+      end
+    end
+
     
     def edit_path( path )
       path
     end
 
-    class << self
-      def Proxy( p_addr, p_port )
-        klass = super
-        klass.module_eval %-
-          def edit_path( path )
-            'http://' + address +
-              (@port == #{self.port} ? '' : ':' + @port.to_s) + path
-          end
-        -
-        klass
-      end
+    def HTTP.Proxy( p_addr, p_port = nil )
+      klass = super
+      klass.module_eval %-
+        def edit_path( path )
+          'http://' + address +
+              (@port == HTTP.port ? '' : ":#{@port}") +
+              path
+        end
+      -
+      klass
     end
 
   end
@@ -521,10 +561,11 @@
   HTTPVersionNotSupported           = HTTPFatalErrorCode.mkchild
 
 
-  class HTTPReadAdapter
+  class HTTPResponseReceiver
 
-    def initialize( command )
+    def initialize( command, body_exist )
       @command = command
+      @body_exist = body_exist
       @header = @body = nil
     end
 
@@ -534,7 +575,9 @@
 
     def header
       unless @header then
-        @header = @command.get_response
+        stream_check
+        @header = @body_exist ? @command.get_response :
+                                @command.get_response_no_body
       end
       @header
     end
@@ -543,20 +586,31 @@
     def body( dest = nil, &block )
       dest, ret = HTTP.procdest( dest, block )
       unless @body then
-        @body = @command.get_body( response, dest )
+        stream_check
+        @body = @command.get_body( header, dest )
       end
       @body
     end
     alias entity body
 
-    def off
-      body
+    def terminate
+      header
+      body if @body_exist
       @command = nil
-      @header
     end
+
+    private
+
+    def stream_check
+      unless @command then
+        raise IOError, 'receiver was used out of block'
+      end
+    end
   
   end
 
+  HTTPReadAdapter = HTTPResponseReceiver
+
 
 
   module NetPrivate
@@ -570,11 +624,8 @@
       @http_version = HTTPVersion
 
       @in_header = {}
-      if sock.port == HTTP.port
-        @in_header[ 'Host' ] = sock.addr
-      else
-        @in_header[ 'Host' ] = sock.addr + ':' + sock.port
-      end
+      @in_header[ 'Host' ] = sock.addr +
+                             ((sock.port == HTTP.port) ? '' : ":#{sock.port}")
       @in_header[ 'Connection' ] = 'Keep-Alive'
       @in_header[ 'Accept' ]     = '*/*'
 

In This Thread