なひです.

> From: TAKAHASHI Masayoshi [mailto:maki / inac.co.jp]
> Sent: Tuesday, June 08, 1999 12:19 AM

> > HTTP/1.1 だと Host ヘッダが使えるのは大きいと思うです。
> 
> えっと、クライアントがHTTP/1.0のリクエストを送っても、Hostヘッダに
> 対応したサーバならちゃんとHostヘッダみてくれませんか?

実装依存ですが,見てくれそうな気がしますね.
HTTP/1.0(RFC1945)には,Hostフィールドについての記述がないので...
どこ見たらいいのやら.
RFC2068にも記述はなさそうだし(アタリマエか...^^;

えーと,結局なひは,
「Hostヘッダが使えるのは大きい」の意味がわかってないような気がします.

> > テスト環境がない(未だにHTTP/1.0のサイトってどこだろう ^^;)
> 
> biglobeです……。
> # たとえば、 http://www2c.biglobe.ne.jp/~hosoda/ とか(^^;

おー,びぐろーぶさん.Netscape-Commerce/1.1か...
数年前に一部システムづくりの
お手伝いした頃から,ウェブサーバ変わってないかも.^^;

ということで,テスト環境が見つかったので,
http-access-0.0.1のPatch作ってみました.
ただしhttp-access.rb本体と,url-parse.rbだけです.
wbrowser等はチェックしてません.

# 状態遷移は...これでいいのかな...自信なし.

ヘッダ区切りがCRLFでなくLFのみ,というサーバに対応しちゃってますが,
この部分は不要かもしれません.
正しいヘッダを誤って解釈する可能性があります.

> # 素直に青山さんのコード借りれば良かったかしらん(^^;;

用途限定なら,その方がいいかもしれませんね.^^;

	/	/	/

diff -ur http-access-0.0.1.dist/http-access.rb http-access-0.0.1/http-access.rb
--- http-access-0.0.1.dist/http-access.rb	Wed Mar  3 16:23:02 1999
+++ http-access-0.0.1/http-access.rb	Tue Jun  8 11:34:55 1999
@@ -29,7 +29,7 @@
 
   def initialize(host, port=HTTP_Port, proxy=nil)
     @host = host
-    @port = port
+    @port = port || HTTP_Port
     @state = :INIT
     @requests = []
     @uagent = format("HTTPAccess/0.0.1 (%s; %s)",
@@ -54,8 +54,8 @@
     header = {} unless header.kind_of? Hash
     header['Host'] = @host unless header['Host']
     header['User-Agent'] = @uagent unless header['User-Agent']
-    #header['Connection'] = 'Keep-Alive' unless header['Connection']
-    #header['Accept'] = '*/*' unless header['Accept']
+    header['Connection'] = 'Keep-Alive' unless header['Connection']
+    header['Accept'] = '*/*' unless header['Accept']
     header.each {|k, v|
       @socket.putheader(k, v)
     }
@@ -97,8 +97,8 @@
 
     req = @requests.shift
 
-    @status_line = @socket.gets("\r\n")
-    unless /(HTTP\/1\.\d+)\s+(\d\d\d)\s+(.*)/ =~ @status_line
+    @status_line = @socket.gets
+    unless /^(HTTP\/1\.\d+)\s+(\d\d\d)\s+(.*)\r?$/ =~ @status_line
       raise HTTPBadResponse
     end
     @http_version = $1
@@ -107,7 +107,7 @@
     @next_connection = true if @http_version == 'HTTP/1.1'
 
     @headers = []
-    until (line = @socket.gets("\r\n")) == "\r\n"
+    until (line = @socket.gets) =~ /^\r?$/
       if line == /^\s/
 	@headers[-1] << line
       else
@@ -117,6 +117,7 @@
 
     @content_length = nil
     @chunked = false
+    @next_connection = false
     @headers.each {|line|
       case line
       when /^Content-Length:\s+(\d+)/i
@@ -139,6 +140,11 @@
     @state = :DATA
     if req[0] == 'HEAD'
       @content_length = 0
+      if @next_connection
+      	@state = :WAIT
+      else
+     	close
+      end
     end
 
     @next_connection = false unless @content_length
@@ -148,7 +154,7 @@
 
   def get_header(&block)
     get_response if @state == :META
-    raise HTTPInvalidState, 'state != DATA' unless @state == :DATA
+    #raise HTTPInvalidState, 'state != DATA' unless @state == :DATA
     if block
       @headers.each {|line|
 	block.call(line)
@@ -179,6 +185,11 @@
     else
       read_body(maxbytes)
     end
+    if @next_connection
+      @state = :WAIT
+    else
+      close
+    end
   end
 
   def read_body(maxbytes=nil)
@@ -254,11 +265,22 @@
   url = URL.new(urlstr)
   #exit
 
-  h = HTTPAccess.new(url.netloc)
+  h = HTTPAccess.new(url.host, url.port)
+  h.request_head(url.path)
+  h.get_response
+  h.get_header {|line| p line}
+  #
   h.request_head(url.path)
+  h.get_response
+  h.get_header {|line| p line}
+  #
   h.request_get(url.path, 'User-Agent'=>'FooBar/1.0')
   h.get_response
   h.get_header {|line| p line}
+  h.get_data(8192) {|data| p data}
+  #
+  h.request_get(url.path, 'User-Agent'=>'FooBar/1.0')
   h.get_response
+  h.get_header {|line| p line}
   h.get_data(8192) {|data| p data}
 end
diff -ur http-access-0.0.1.dist/url-parse.rb http-access-0.0.1/url-parse.rb
--- http-access-0.0.1.dist/url-parse.rb	Wed Mar  3 16:20:08 1999
+++ http-access-0.0.1/url-parse.rb	Tue Jun  8 10:17:41 1999
@@ -1,6 +1,6 @@
 # Parse URLs.
 class URL
-  attr_reader :urlstr, :scheme, :netloc, :path, :params, :query, :fragment
+  attr_reader :urlstr, :scheme, :netloc, :host, :port, :path, :params, :query, :fragment
 
   Uses_netloc = ['ftp', 'http', 'gopher', 'nntp', 'telnet', 'wais',
     'https', 'shttp', 'snews', 'prospero', '']
@@ -14,15 +14,20 @@
   # [scheme]://[netloc]/[path];[params]?[query]#[fragment]
   def parse(url, scheme = nil, allow_fragments = true)
     @scheme = scheme
-    @netloc = @params = @query = @fragment = nil
+    @netloc = @host = @port = @params = @query = @fragment = nil
 
     if url =~ /^([-+\.\w]+):/
       @scheme, url = $1, $' #'
     end
 
     if url =~ /^(\/\/)?([^\/]+)/ && Uses_netloc.include?(@scheme)
-      # //[netloc]
+      # //[netloc] a.k.a. hostport ::= host [ : port ] in RFC1630
       @netloc, url = $2, $' #'
+      if @netloc =~ /^([^:]+):(\d*)$/	# Is this valid like 'http://foo:/bar'?
+      	@host, @port = $1, $2
+      else
+	@host = @netloc
+      end
     elsif url =~ /^(\/|~)/
       @scheme = 'file'
     else