summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authoraamine <aamine@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2001-07-08 07:01:22 +0000
committeraamine <aamine@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2001-07-08 07:01:22 +0000
commit9f236c6c605fe451a40e200b8ab75908866b637f (patch)
tree875d7ce784dca4deb35207be4b31e16e93e90110 /lib
parent49cc90d6c11f1fc9105901683dc36ccddf7df9d2 (diff)
aamine
* lib/net/protocol.rb (ProtoSocket#read): modify typo. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_6@1578 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib')
-rw-r--r--lib/net/http.rb354
-rw-r--r--lib/net/pop.rb4
-rw-r--r--lib/net/protocol.rb13
-rw-r--r--lib/net/smtp.rb6
4 files changed, 204 insertions, 173 deletions
diff --git a/lib/net/http.rb b/lib/net/http.rb
index 204d140892..47c3853e6e 100644
--- a/lib/net/http.rb
+++ b/lib/net/http.rb
@@ -1,6 +1,6 @@
=begin
-= net/http.rb version 1.1.35
+= net/http.rb version 1.1.36
Copyright (c) 1999-2001 Yukihiro Matsumoto
@@ -203,7 +203,7 @@ Yes, this is not thread-safe.
: finish
finishes HTTP session.
- If HTTP session had not started, do nothing and return false.
+ If HTTP session had not started, raises an IOError.
: proxy?
true if self is a HTTP proxy class
@@ -266,10 +266,7 @@ Yes, this is not thread-safe.
Net::HTTP.start( 'some.www.server', 80 ) {|http|
response = http.head( '/index.html' )
}
- response['content-length'] #-> '2554'
- response['content-type'] #-> 'text/html'
- response['Content-Type'] #-> 'text/html'
- response['CoNtEnT-tYpe'] #-> 'text/html'
+ p response['content-type']
: post( path, data, header = nil, dest = '' )
: post( path, data, header = nil ) {|str| .... }
@@ -286,71 +283,66 @@ Yes, this is not thread-safe.
by "anException.response".
# version 1.1
- response, body = http.post( '/index.html', 'querytype=subject&target=ruby' )
+ response, body = http.post( '/cgi-bin/search.rb', 'querytype=subject&target=ruby' )
# version 1.2
- response = http.post( '/index.html', 'querytype=subject&target=ruby' )
+ response = http.post( '/cgi-bin/search.rb', 'querytype=subject&target=ruby' )
# compatible for both version
- response , = http.post( '/index.html', 'querytype=subject&target=ruby' )
+ response , = http.post( '/cgi-bin/search.rb', 'querytype=subject&target=ruby' )
# using block
File.open( 'save.html', 'w' ) {|f|
- http.post( '/index.html', 'querytype=subject&target=ruby' ) do |str|
+ http.post( '/cgi-bin/search.rb', 'querytype=subject&target=ruby' ) do |str|
f.write str
end
}
# same effect
File.open( 'save.html', 'w' ) {|f|
- http.post '/index.html', 'querytype=subject&target=ruby', nil, f
+ http.post '/cgi-bin/search.rb', 'querytype=subject&target=ruby', nil, f
}
-: request( request [, data] )
-: request( request [, data] ) {|response| .... }
- sends a HTTPRequest object REQUEST to (remote) http server.
- This method also writes string from DATA string if REQUEST is
- a post/put request. Giving DATA for get/head request causes
- ArgumentError.
+: get2( path, header = nil )
+: get2( path, header = nil ) {|response| .... }
+ gets entity from PATH. This method returns a HTTPResponse object.
- If called with block, gives a HTTPResponse object to the block
- with connecting server.
+ When called with block, keep connection while block is executed
+ and gives a HTTPResponse object to the block.
-== class Net::HTTP::Get, Head, Post
+ This method never raise any ProtocolErrors.
-HTTP request classes. These classes wraps request header and
-entity path. All arguments named "key" is case-insensitive.
-
-=== Class Methods
-
-: new
- creats HTTP request object.
-
-=== Instance Methods
-
-: self[ key ]
- returns the header field corresponding to the case-insensitive key.
- For example, a key of "Content-Type" might return "text/html"
-
-: self[ key ] = val
- sets the header field corresponding to the case-insensitive key.
+ # example
+ response = http.get2( '/index.html' )
+ p response['content-type']
+ puts response.body # body is already read
-: each {|name, val| .... }
- iterates for each field name and value pair.
+ # using block
+ http.get2( '/index.html' ) {|response|
+ p response['content-type']
+ response.read_body do |str| # read body now
+ print str
+ end
+ }
-: basic_auth( account, password )
- set Authorization: header for basic auth.
+: post2( path, header = nil )
+: post2( path, header = nil ) {|response| .... }
+ posts data to PATH. This method returns a HTTPResponse object.
-: range
- returns a Range object which represents Range: header field.
+ When called with block, gives a HTTPResponse object to the block
+ before reading entity body, with keeping connection.
-: range = r
-: set_range( i, len )
- set Range: header from Range (arg r) or beginning index and
- length from it (arg i&len).
+ # example
+ response = http.post2( '/cgi-bin/nice.rb', 'datadatadata...' )
+ p response.status
+ puts response.body # body is already read
-: content_length
- returns a Integer object which represents Content-Length: header field.
+ # using block
+ http.post2( '/cgi-bin/nice.rb', 'datadatadata...' ) {|response|
+ p response.status
+ p response['content-type']
+ response.read_body do |str| # read body now
+ print str
+ end
+ }
-: content_range
- returns a Range object which represents Content-Range: header field.
== class Net::HTTPResponse
@@ -397,7 +389,6 @@ All arguments named KEY is case-insensitive.
response body. If #read_body has been called, this method returns
arg of #read_body DEST. Else gets body as String and returns it.
-
=end
require 'net/protocol'
@@ -565,7 +556,7 @@ module Net
public
- def self.def_http_method( nm, hasdest, hasdata )
+ def self.define_http_method_interface( nm, hasdest, hasdata )
name = nm.id2name.downcase
cname = nm.id2name
lineno = __LINE__ + 2
@@ -596,36 +587,46 @@ module Net
module_eval src, __FILE__, lineno
end
- def_http_method :Get, true, false
- def_http_method :Head, false, false
- def_http_method :Post, true, true
- def_http_method :Put, false, true
+ define_http_method_interface :Get, true, false
+ define_http_method_interface :Head, false, false
+ define_http_method_interface :Post, true, true
+ define_http_method_interface :Put, false, true
- def request( req, *args )
- common_oper( req ) {
+ def request( req, body = nil )
+ connecting( req ) {
req.__send__( :exec,
- @socket, @curr_http_version, edit_path(req.path), *args )
+ @socket, @curr_http_version, edit_path(req.path), body )
yield req.response if block_given?
}
req.response
end
+ def send_request( name, path, body = nil, header = nil )
+ r = ::Net::NetPrivate::HTTPGenericRequest.new(
+ name, (body ? true : false), true,
+ path, header )
+ request r, body
+ end
+
private
- def common_oper( req )
- req['connection'] ||= 'keep-alive'
+ def connecting( req )
+ unless active? then
+ implicit = true
+ req['connection'] ||= 'close'
+ end
+
if not @socket then
start
- req['connection'] = 'close'
elsif @socket.closed? then
re_connect
end
if not req.body_exist? or @seems_1_0_server then
req['connection'] = 'close'
end
- req['host'] = addr_port
+ req['host'] = addr_port()
yield req
req.response.__send__ :terminate
@@ -645,7 +646,9 @@ module Net
@socket.close
end
- req.response
+ if implicit then
+ finish
+ end
end
def keep_alive?( req, res )
@@ -836,9 +839,9 @@ module Net
d1 = m[1].to_i
d2 = m[2].to_i
- if m[1] and m[2] then arr.push d1..d2
- elsif m[1] then arr.push d1..-1
- elsif m[2] then arr.push -d2..-1
+ if m[1] and m[2] then arr.push( d1..d2 )
+ elsif m[1] then arr.push( d1..-1 )
+ elsif m[2] then arr.push( -d2..-1 )
else
raise HTTPHeaderSyntaxError, 'range is not specified'
end
@@ -915,21 +918,22 @@ module Net
end
- }
-
###
### request
###
- net_private {
-
- class HTTPRequest
+ class HTTPGenericRequest
include ::Net::NetPrivate::HTTPHeader
- def initialize( path, uhead = nil )
+ def initialize( m, reqbody, resbody, path, uhead = nil )
+ @method = m
+ @request_has_body = reqbody
+ @response_has_body = resbody
@path = path
+ @response = nil
+
@header = tmp = {}
return unless uhead
uhead.each do |k,v|
@@ -940,11 +944,9 @@ module Net
tmp[ key ] = v.strip
end
tmp['accept'] ||= '*/*'
-
- @socket = nil
- @response = nil
end
+ attr_reader :method
attr_reader :path
attr_reader :response
@@ -952,10 +954,16 @@ module Net
"\#<#{type}>"
end
- def body_exist?
- type::HAS_BODY
+ def request_body_permitted?
+ @request_has_body
+ end
+
+ def response_body_permitted?
+ @response_has_body
end
+ alias body_exist? response_body_permitted?
+
private
@@ -963,113 +971,92 @@ module Net
# write
#
- def exec( sock, ver, path )
- ready( sock ) {
- request ver, path
- }
- @response
- end
-
- def ready( sock )
- @response = nil
- @socket = sock
- yield
- @response = get_response
- @socket = nil
- end
-
- def request( ver, path )
- @socket.writeline sprintf('%s %s HTTP/%s', type::METHOD, path, ver)
- canonical_each do |k,v|
- @socket.writeline k + ': ' + v
+ def exec( sock, ver, path, body, &block )
+ if body then
+ check_body_premitted
+ check_arg_b body, block
+ sendreq_with_body sock, ver, path, body, &block
+ else
+ check_arg_n body
+ sendreq_no_body sock, ver, path
end
- @socket.writeline ''
+ @response = r = get_response( sock )
+ r
end
- #
- # read
- #
-
- def get_response
- begin
- resp = read_response
- end while ContinueCode === resp
- resp
+ def check_body_premitted
+ request_body_permitted? or
+ raise ArgumentError, 'HTTP request body is not premitted'
end
- def read_response
- resp = get_resline
-
- while true do
- line = @socket.readuntil( "\n", true ) # ignore EOF
- line.sub!( /\s+\z/, '' ) # don't use chop!
- break if line.empty?
-
- m = /\A([^:]+):\s*/.match( line )
- m or raise HTTPBadResponse, 'wrong header line format'
- nm = m[1]
- line = m.post_match
- if resp.key? nm then
- resp[nm] << ', ' << line
- else
- resp[nm] = line
- end
+ def check_arg_b( data, block )
+ if data and block then
+ raise ArgumentError, 'both of data and block given'
+ end
+ unless data or block then
+ raise ArgumentError, 'str or block required'
end
-
- resp
end
- def get_resline
- str = @socket.readline
- m = /\AHTTP(?:\/(\d+\.\d+))?\s+(\d\d\d)\s*(.*)\z/i.match( str )
- m or raise HTTPBadResponse, "wrong status line: #{str}"
- httpver = m[1]
- status = m[2]
- discrip = m[3]
-
- ::Net::NetPrivate::HTTPResponse.new(
- status, discrip, @socket, type::HAS_BODY, httpver )
+ def check_arg_n( data )
+ data and raise ArgumentError, "data is not permitted for #{@method}"
end
-
- end
-
- class HTTPRequestWithBody < HTTPRequest
-
- private
- def exec( sock, ver, path, str = nil )
- check_arg str, block_given?
+ def sendreq_no_body( sock, ver, path )
+ request sock, ver, path
+ end
+ def sendreq_with_body( sock, ver, path, body )
if block_given? then
ac = Accumulator.new
yield ac # must be yield, DO NOT USE block.call
data = ac.terminate
else
- data = str
+ data = body
end
@header['content-length'] = data.size.to_s
@header.delete 'transfer-encoding'
- ready( sock ) {
- request ver, path
- @socket.write data
- }
- @response
+ request sock, ver, path
+ sock.write data
end
- def check_arg( data, blkp )
- if data and blkp then
- raise ArgumentError, 'both of data and block given'
- end
- unless data or blkp then
- raise ArgumentError, 'str or block required'
+ def request( sock, ver, path )
+ sock.writeline sprintf('%s %s HTTP/%s', @method, path, ver)
+ canonical_each do |k,v|
+ sock.writeline k + ': ' + v
end
+ sock.writeline ''
+ end
+
+ #
+ # read
+ #
+
+ def get_response( sock )
+ begin
+ resp = ::Net::NetPrivate::HTTPResponse.new_from_socket(sock,
+ response_body_permitted?)
+ end while ContinueCode === resp
+ resp
end
end
+ class HTTPRequest < HTTPGenericRequest
+
+ def initialize( path, uhead = nil )
+ super type::METHOD,
+ type::REQUEST_HAS_BODY,
+ type::RESPONSE_HAS_BODY,
+ path, uhead
+ end
+
+ end
+
+
class Accumulator
def initialize
@@ -1099,23 +1086,27 @@ module Net
class HTTP
class Get < ::Net::NetPrivate::HTTPRequest
- HAS_BODY = true
METHOD = 'GET'
+ REQUEST_HAS_BODY = false
+ RESPONSE_HAS_BODY = true
end
class Head < ::Net::NetPrivate::HTTPRequest
- HAS_BODY = false
METHOD = 'HEAD'
+ REQUEST_HAS_BODY = false
+ RESPONSE_HAS_BODY = false
end
- class Post < ::Net::NetPrivate::HTTPRequestWithBody
- HAS_BODY = true
+ class Post < ::Net::NetPrivate::HTTPRequest
METHOD = 'POST'
+ REQUEST_HAS_BODY = true
+ RESPONSE_HAS_BODY = true
end
- class Put < ::Net::NetPrivate::HTTPRequestWithBody
- HAS_BODY = true
+ class Put < ::Net::NetPrivate::HTTPRequest
METHOD = 'PUT'
+ REQUEST_HAS_BODY = true
+ RESPONSE_HAS_BODY = true
end
end
@@ -1184,6 +1175,45 @@ module Net
'505' => HTTPVersionNotSupported
}
+
+ class << self
+
+ def new_from_socket( sock, hasbody )
+ resp = readnew( sock, hasbody )
+
+ while true do
+ line = sock.readuntil( "\n", true ) # ignore EOF
+ line.sub!( /\s+\z/, '' ) # don't use chop!
+ break if line.empty?
+
+ m = /\A([^:]+):\s*/.match( line )
+ m or raise HTTPBadResponse, 'wrong header line format'
+ nm = m[1]
+ line = m.post_match
+ if resp.key? nm then
+ resp[nm] << ', ' << line
+ else
+ resp[nm] = line
+ end
+ end
+
+ resp
+ end
+
+ private
+
+ def readnew( sock, hasbody )
+ str = sock.readline
+ m = /\AHTTP(?:\/(\d+\.\d+))?\s+(\d\d\d)\s*(.*)\z/in.match( str )
+ m or raise HTTPBadResponse, "wrong status line: #{str}"
+ discard, httpv, stat, desc = *m.to_a
+
+ new( stat, desc, sock, hasbody, httpv )
+ end
+
+ end
+
+
def initialize( stat, msg, sock, be, hv )
code = CODE_TO_OBJ[stat] ||
CODE_CLASS_TO_OBJ[stat[0,1]] ||
diff --git a/lib/net/pop.rb b/lib/net/pop.rb
index 9daf68013b..32394acf00 100644
--- a/lib/net/pop.rb
+++ b/lib/net/pop.rb
@@ -1,6 +1,6 @@
=begin
-= net/pop.rb version 1.1.35
+= net/pop.rb version 1.1.36
Copyright (c) 1999-2001 Yukihiro Matsumoto
@@ -201,7 +201,7 @@ net/pop also supports APOP authentication. There's two way to use APOP:
: finish
finishes POP3 session.
- If POP3 session had not be started, does nothing and return false.
+ If POP3 session had not be started, raises an IOError.
: mails
an array of Net::POPMail objects.
diff --git a/lib/net/protocol.rb b/lib/net/protocol.rb
index 28ffab5c72..9504356876 100644
--- a/lib/net/protocol.rb
+++ b/lib/net/protocol.rb
@@ -1,6 +1,6 @@
=begin
-= net/protocol.rb version 1.1.35
+= net/protocol.rb version 1.1.36
Copyright (c) 1999-2001 Yukihiro Matsumoto
@@ -32,7 +32,7 @@ module Net
class Protocol
- Version = '1.1.35'
+ Version = '1.1.36'
class << self
@@ -122,7 +122,7 @@ module Net
#
def start( *args )
- return false if active?
+ active? and raise IOError, 'protocol has been opened already'
if block_given? then
begin
@@ -134,6 +134,7 @@ module Net
else
_start args
end
+ nil
end
private
@@ -177,12 +178,12 @@ module Net
public
def finish
- return false unless active?
+ active? or raise IOError, 'already closed protocol'
do_finish if @command and not @command.critical?
disconnect
@active = false
- true
+ nil
end
private
@@ -531,7 +532,7 @@ module Net
CRLF = "\r\n"
- def read( len, dest = '', ignerr = false )
+ def read( len, dest = '', igneof = false )
D_off "reading #{len} bytes..."
rsize = 0
diff --git a/lib/net/smtp.rb b/lib/net/smtp.rb
index d478d927b6..f60cc6edb7 100644
--- a/lib/net/smtp.rb
+++ b/lib/net/smtp.rb
@@ -1,6 +1,6 @@
=begin
-= net/smtp.rb version 1.1.35
+= net/smtp.rb version 1.1.36
Copyright (c) 1999-2001 Yukihiro Matsumoto
@@ -108,8 +108,8 @@ send or reject SMTP session by this data.
: start( helo_domain = <local host name>, account = nil, password = nil, authtype = nil )
: start( helo_domain = <local host name>, account = nil, password = nil, authtype = nil ) {|smtp| .... }
opens TCP connection and starts SMTP session.
- If protocol had been started, do nothing and return false.
HELO_DOMAIN is a domain that you'll dispatch mails from.
+ If protocol had been started, raises IOError.
When this methods is called with block, give a SMTP object to block and
close session after block call finished.
@@ -141,7 +141,7 @@ send or reject SMTP session by this data.
: finish
finishes SMTP session.
- If SMTP session had not started, do nothing and return false.
+ If SMTP session had not started, raises an IOError.
: send_mail( mailsrc, from_addr, *to_addrs )
This method sends MAILSRC as mail. A SMTP object read strings