あおきです。
In mail "[ruby-list:23277] net/smtp.rb extra lines ?"
"Kikutani, Makoto" <kikutani / Galaxy.net> wrote:
> どうも、最近自分の出したメイルに2行くらい余計な空行が最後に
> 付いているのに気付いたので、まあcurのバグに違いないと思っていろいろ
> 調べたのですが、
> なんてのを実行しても、やはり余計な空行が付きますね。
> これは使いかたが悪いのか、あるいは net/smtp.rb の問題なのでしょうか?
一行は smtp のバグでした。ごめんなさい。後の一行は謎です。
とりあえず以下のパッチ試してください。
チェックインもします。
> # どうもnetの下は難しすぎていつも追えない。protocol.rb の each_crlf_line
> # あたりまで行ってギブアップ
そうですか。ぼくは ごく普通に書いてるつもりなんですが(あたりまえか)、
「net/* は理解できない」という声がよくあがるので ちょっと悩んでます。
-------------------------------------------------------------------
あおきみねろう
Index: protocol.rb
===================================================================
RCS file: /home/aamine/cvs/maillib/protocol.rb,v
retrieving revision 1.2.2.21
retrieving revision 1.2.2.23
diff -u -r1.2.2.21 -r1.2.2.23
--- protocol.rb 2000/06/12 16:33:45 1.2.2.21
+++ protocol.rb 2000/06/16 10:34:56 1.2.2.23
@@ -7,15 +7,6 @@
This library is distributed under the terms of the Ruby license.
You can freely distribute/modify this library.
-=end
-
-
-require 'socket'
-
-
-module Net
-
-=begin
== Net::Protocol
@@ -66,10 +57,16 @@
=end
+require 'socket'
+
+
+module Net
+
class Protocol
Version = '1.1.22'
+
class << self
def start( address = 'localhost', port = nil, *args )
@@ -480,9 +477,6 @@
CRLF = "\r\n"
- D_CRLF = ".\r\n"
- TERMEXP = /\n|\r\n|\r/o
-
def read( len, dest = '' )
@pipe << "reading #{len} bytes...\n" if @pipe; pipeoff
@@ -531,7 +525,7 @@
def readline
- ret = readuntil( CRLF )
+ ret = readuntil( "\r\n" )
ret.chop!
ret
end
@@ -542,9 +536,9 @@
rsize = 0
- while (str = readuntil( CRLF )) != D_CRLF do
+ while (str = readuntil( "\r\n" )) != ".\r\n" do
rsize += str.size
- str.gsub!( /\A\./o, '' )
+ str.gsub!( /\A\./, '' )
dest << str
end
@@ -559,7 +553,7 @@
arr = []
str = nil
- while (str = readuntil( CRLF )) != D_CRLF do
+ while (str = readuntil( "\r\n" )) != ".\r\n" do
str.chop!
arr.push str
yield str if iterator?
@@ -602,7 +596,7 @@
def writeline( str )
do_write_beg
do_write_do str
- do_write_do CRLF
+ do_write_do "\r\n"
do_write_fin
end
@@ -629,8 +623,7 @@
else
write_pendstr_inner src
end
- each_crlf_line2( :i_w_pend )
- do_write_do D_CRLF
+ do_write_do ".\r\n"
wsize = do_write_fin
@pipe << "wrote #{wsize} bytes text\n" if pipeon
@@ -657,32 +650,40 @@
def each_crlf_line( src, mid )
- beg = 0
- buf = pos = s = bin = nil
+ buf = ''
+ str = m = nil
- adding( src ) do
- beg = 0
- buf = @wbuf
+ adding( src, buf ) do
while true do
- pos = buf.index( TERMEXP, beg )
- break unless pos
- s = $&.size
- break if pos + s == buf.size - 1 and buf[-1] == ?\r
+ m = /[^\r\n]*(\n|\r\n|\r)/.match( buf )
+ break unless m
- __send__ mid, buf[ beg, pos - beg ] << CRLF
- beg = pos + s
+ str = m[0]
+ if str.size == buf.size and buf[-1] == ?\r then
+ # "...\r" : can follow "\n..."
+ break
+ end
+ buf[ 0, str.size ] = ''
+ str.chop!
+ str.concat "\r\n"
+ __send__ mid, str
end
- @wbuf = buf[ beg, buf.size - beg ] if beg != 0
+ end
+ if not buf.empty? then # un-terminated last line
+ buf.concat "\r\n"
+ __send__ mid, buf
+ elsif not str then # empty src
+ __send__ mid, "\r\n"
end
end
- def adding( src )
+ def adding( src, buf )
i = nil
case src
when String
0.step( src.size, 512 ) do |i|
- @wbuf << src[ i, 512 ]
+ buf << src[ i, 512 ]
yield
end
@@ -690,38 +691,22 @@
while true do
i = src.read( 512 )
break unless i
- @wbuf << i
+ buf << i
yield
end
else
src.each do |bin|
- @wbuf << bin
- yield if @wbuf.size > 512
+ buf << bin
+ yield if buf.size > 512
end
end
end
- def each_crlf_line2( mid )
- buf = @wbuf
- beg = pos = nil
-
- buf << "\n" unless /\n|\r/o === buf[-1,1]
-
- beg = 0
- while true do
- pos = buf.index( TERMEXP, beg )
- break unless pos
- __send__ mid, buf[ beg, pos - beg ] << CRLF
- beg = pos + $&.size
- end
- end
-
def do_write_beg
@writtensize = 0
@sending = ''
- @wbuf = ''
end
def do_write_do( arg )