summaryrefslogtreecommitdiff
path: root/lib/net/http.rb
diff options
context:
space:
mode:
authoraamine <aamine@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2001-06-26 23:49:21 +0000
committeraamine <aamine@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2001-06-26 23:49:21 +0000
commitc664027a342785089cc09169ff167350e840baa9 (patch)
tree2b74c20ddbfd9371414294e4c34ea3ce1e5afe95 /lib/net/http.rb
parent10e80b2402f7c0fd79df86767a11ba4e4b1bfa95 (diff)
aamine
* lib/net/pop.rb: new methods POP3.auth_only, POP3#auth_only * lib/net/http.rb: HTTP.Proxy returns self if ADDRESS is nil. * lib/net/protocol.rb: new method ProtocolError#response * lib/net/protocol.rb,smtp.rb,pop.rb,http.rb: add document. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1546 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/net/http.rb')
-rw-r--r--lib/net/http.rb488
1 files changed, 328 insertions, 160 deletions
diff --git a/lib/net/http.rb b/lib/net/http.rb
index bbe98274f4..6a8fc5f862 100644
--- a/lib/net/http.rb
+++ b/lib/net/http.rb
@@ -1,125 +1,304 @@
=begin
-= net/http.rb version 1.2.0
+= net/http.rb version 1.2.1
- Copyright (C) 1999-2001 Yukihiro Matsumoto
+Copyright (c) 1999-2001 Yukihiro Matsumoto
- written & maintained by Minero Aoki <aamine@dp.u-netsurf.ne.jp>
- This file is derived from "http-access.rb".
+written & maintained by Minero Aoki <aamine@loveruby.net>
+This file is derived from "http-access.rb".
- This program is free software. You can re-distribute and/or
- modify this program under the same terms as Ruby itself,
- GNU General Public License or Ruby License.
+This program is free software. You can re-distribute and/or
+modify this program under the same terms as Ruby itself,
+Ruby Distribute License or GNU General Public License.
- Japanese version of this document is in "net" full package.
- You can get it from RAA (Ruby Application Archive). RAA is:
- http://www.ruby-lang.org/en/raa.html
+NOTE: You can get Japanese version of this document from
+Ruby Documentation Project (RDP):
+((<URL:http://www.ruby-lang.org/~rubikitch/RDP.cgi>))
+== What is this module?
+
+This module provide your program the functions to access WWW
+documents via HTTP, Hyper Text Transfer Protocol version 1.1.
+For details of HTTP, refer [RFC2616]
+((<URL:http://www.ietf.org/rfc/rfc2616.txt>)).
+
+== Examples
+
+=== Getting Document From Server
+
+Be care to ',' (comma) putted after "response".
+This is required for feature compatibility.
+
+ require 'net/http'
+ Net::HTTP.start( 'some.www.server', 80 ) {|http|
+ response , = http.get('/index.html')
+ puts response.body
+ }
+
+(shorter version)
+
+ require 'net/http'
+ Net::HTTP.get_print 'some.www.server', '/index.html'
+
+=== Posting Form Data
+
+ require 'net/http'
+ Net::HTTP.start( 'some.www.server', 80 ) {|http|
+ response , = http.post( '/cgi-bin/any.rhtml',
+ 'querytype=subject&target=ruby' )
+ }
+
+=== Accessing via Proxy
+
+Net::HTTP.Proxy() creates http proxy class. It has same
+methods of Net::HTTP but its instances always connect to
+proxy, instead of given host.
+
+ require 'net/http'
+
+ $proxy_addr = 'your.proxy.addr'
+ $proxy_port = 8080
+ :
+ Net::HTTP::Proxy($proxy_addr, $proxy_port).start( 'some.www.server' ) {|http|
+ # always connect to your.proxy.addr:8080
+ :
+ }
+
+Since Net::HTTP.Proxy() returns Net::HTTP itself when $proxy_addr is nil,
+there's no need to change code if there's proxy or not.
+
+=== Redirect
+
+ require 'net/http'
+ Net::HTTP.version_1_1
+
+ host = 'www.ruby-lang.org'
+ begin
+ Net::HTTP.start( host, 80 ) {|http|
+ response , = http.get('/')
+ }
+ rescue Net::ProtoRetriableError => err
+ if m = %r<http:([^/]+)>.match( err.response['location'] ) then
+ host = m[1].strip
+ retry
+ end
+ end
+
+NOTE: This code is using ad-hoc way to extract host name, but in future
+URI class will be included in ruby standard library.
+
+=== Basic Authentication
+
+ require 'net/http'
+
+ Net::HTTP.start( 'auth.some.domain' ) {|http|
+ response , = http.get( '/need-auth.cgi',
+ 'Authentication' => ["#{account}:#{password}"].pack('m').strip )
+ print response.body
+ }
+
+In version 1.2 (Ruby 1.7 or later), you can write like this:
+
+ require 'net/http'
+
+ req = Net::HTTP::Get.new('/need-auth.cgi')
+ req.basic_auth 'account', 'password'
+ Net::HTTP.start( 'auth.some.domain' ) {|http|
+ response = http.request( req )
+ print response.body
+ }
+
+== Switching Net::HTTP versions
+
+You can use old Net::HTTP (in Ruby 1.6) features by calling
+HTTP.version_1_1. And calling Net::HTTP.version_1_2 allows
+you to use 1.2 features again.
+
+ # example
+ Net::HTTP.start {|http1| ...(http1 has 1.2 features)... }
+
+ Net::HTTP.version_1_1
+ Net::HTTP.start {|http2| ...(http2 has 1.1 features)... }
+
+ Net::HTTP.version_1_2
+ Net::HTTP.start {|http3| ...(http3 has 1.2 features)... }
+
+Yes, this is not thread-safe.
== class Net::HTTP
=== Class Methods
: new( address = 'localhost', port = 80, proxy_addr = nil, proxy_port = nil )
- creates a new Net::HTTP object.
- If proxy_addr is given, this method is equals to
- Net::HTTP::Proxy(proxy_addr,proxy_port).
+ creates a new Net::HTTP object.
+ If proxy_addr is given, this method is equals to
+ Net::HTTP::Proxy(proxy_addr,proxy_port).
: start( address = 'localhost', port = 80, proxy_addr = nil, proxy_port = nil )
: start( address = 'localhost', port = 80, proxy_addr = nil, proxy_port = nil ) {|http| .... }
- is equals to
+ is equals to
- Net::HTTP.new( address, port, proxy_addr, proxy_port ).start(&block)
+ Net::HTTP.new(address, port, proxy_addr, proxy_port).start(&block)
: get( address, path, port = 80 )
- gets entity body from path and returns it.
- return value is a String.
+ gets entity body from path and returns it.
+ return value is a String.
: get_print( address, path, port = 80 )
- gets entity body from path and print it.
- return value is an entity body (a String).
-
-: Proxy( address, port )
- creates a HTTP proxy class.
- Arguments are address/port of proxy host.
- You can replace HTTP class by this proxy class.
-
- # example
- proxy_http = HTTP::Proxy( 'proxy.foo.org', 8080 )
- :
- proxy_http.start( 'www.ruby-lang.org' ) do |http|
- # connecting proxy.foo.org:8080
- :
- end
+ gets entity body from path and print it.
+ return value is an entity body (a String).
+
+: Proxy( address, port = 80 )
+ creates a HTTP proxy class.
+ Arguments are address/port of proxy host.
+ You can replace HTTP class by this proxy class.
+
+ If ADDRESS is nil, this method returns self (Net::HTTP class).
+
+ # example
+ proxy_class = Net::HTTP::Proxy( 'proxy.foo.org', 8080 )
+ :
+ proxy_class.start( 'www.ruby-lang.org' ) do |http|
+ # connecting proxy.foo.org:8080
+ :
+ end
: proxy_class?
- If self is HTTP, false.
- If self is a class which was created by HTTP::Proxy(), true.
+ If self is HTTP, false.
+ If self is a class which was created by HTTP::Proxy(), true.
: port
- HTTP default port (80).
-
+ HTTP default port (80).
=== Instance Methods
: start
: start {|http| .... }
- creates a new Net::HTTP object and starts HTTP session.
+ creates a new Net::HTTP object and starts HTTP session.
+
+ When this method is called with block, gives a HTTP object to block
+ and close the HTTP session after block call finished.
+
+: active?
+ true if HTTP session is started.
+
+: address
+ the address to connect
+
+: port
+ the port number to connect
- When this method is called with block, gives HTTP object to block
- and close HTTP session after block call finished.
+: open_timeout
+: open_timeout=(n)
+ seconds to wait until connection is opened.
+ If HTTP object cannot open a conection in this seconds,
+ it raises TimeoutError exception.
+
+: read_timeout
+: read_timeout=(n)
+ seconds to wait until reading one block (by one read(1) call).
+ If HTTP object cannot open a conection in this seconds,
+ it raises TimeoutError exception.
+
+: finish
+ finishes HTTP session.
+ If HTTP session had not started, do nothing and return false.
: proxy?
- true if self is a HTTP proxy class
+ true if self is a HTTP proxy class
: proxy_address
- address of proxy host. If self is not a proxy, nil.
+ address of proxy host. If self is not a proxy, nil.
: proxy_port
- port number of proxy host. If self is not a proxy, nil.
+ port number of proxy host. If self is not a proxy, nil.
: get( path, header = nil, dest = '' )
: get( path, header = nil ) {|str| .... }
- gets data from "path" on connecting host.
- "header" must be a Hash like { 'Accept' => '*/*', ... }.
- Response body is written into "dest" by using "<<" method.
- This method returns Net::HTTPResponse object.
+ gets data from "path" on connecting host.
+ "header" must be a Hash like { 'Accept' => '*/*', ... }.
+ Response body is written into "dest" by using "<<" method.
+ This method returns Net::HTTPResponse object.
- # example
- response = http.get( '/index.html' )
+ If called with block, give a part String of entity body.
- If called with block, give a part String of entity body.
+ In version 1.1, this method might raises exception for also
+ 3xx (redirect). On the case you can get response object by
+ err.response.
-: head( path, header = nil )
- gets only header from "path" on connecting host.
- "header" is a Hash like { 'Accept' => '*/*', ... }.
- This method returns a Net::HTTPResponse object.
- You can http header from this object like:
+ In version 1.2, this method never raises exception.
- response['content-length'] #-> '2554'
- response['content-type'] #-> 'text/html'
- response['Content-Type'] #-> 'text/html'
- response['CoNtEnT-tYpe'] #-> 'text/html'
+ # version 1.1 (Ruby 1.6)
+ response, body = http.get( '/index.html' )
-: post( path, data, header = nil, dest = '' )
-: post( path, data, header = nil ) {|str| .... }
- posts "data" (must be String) to "path".
- If the body exists, also gets entity body.
- Response body is written into "dest" by using "<<" method.
- "header" must be a Hash like { 'Accept' => '*/*', ... }.
- This method returns Net::HTTPResponse object.
+ # version 1.2 (Ruby 1.7 or later)
+ response = http.get( '/index.html' )
- If called with block, gives a part of entity body string.
+ # compatible in both version
+ response , = http.get( '/index.html' )
+ response.body
+
+ # using block
+ File.open( 'save.txt', 'w' ) {|f|
+ http.get( '/~foo/', nil ) do |str|
+ f.write str
+ end
+ }
+ # some effect
+ File.open( 'save.txt', 'w' ) {|f|
+ http.get '/~foo/', nil, f
+ }
+: head( path, header = nil )
+ gets only header from "path" on connecting host.
+ "header" is a Hash like { 'Accept' => '*/*', ... }.
+ This method returns a Net::HTTPResponse object.
+ You can http header from this object like:
+
+ response = nil
+ 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'
-: request( request, [src] )
-: request( request, [src] ) {|response| .... }
- sends REQUEST to (remote) http server. This method also writes
- string from SRC before it if REQUEST is a post/put request.
- (giving SRC for get/head request causes ArgumentError.)
+: post( path, data, header = nil, dest = '' )
+: post( path, data, header = nil ) {|str| .... }
+ posts "data" (must be String) to "path".
+ If the body exists, also gets entity body.
+ Response body is written into "dest" by using "<<" method.
+ "header" must be a Hash like { 'Accept' => '*/*', ... }.
+ This method returns Net::HTTPResponse object.
+
+ If called with block, gives a part of entity body string.
+
+ # version 1.1
+ response, body = http.post( '/index.html', 'querytype=subject&target=ruby' )
+ # version 1.2
+ response = http.post( '/index.html', 'querytype=subject&target=ruby' )
+ # compatible for both version
+ response , = http.post( '/index.html', 'querytype=subject&target=ruby' )
+
+ # using block
+ File.open( 'save.html', 'w' ) {|f|
+ http.post( '/index.html', '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
+ }
- If called with block, gives a HTTP response object to the block.
+: request( request, [data] )
+: request( request, [src] ) {|response| .... }
+ sends 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.)
+ If called with block, gives a HTTPResponse object to the block.
== class Net::HTTP::Get, Head, Post
@@ -131,7 +310,7 @@ entity path. All arguments named "key" is case-insensitive.
: new
creats HTTP request object.
-=== Methods
+=== Instance Methods
: self[ key ]
returns the header field corresponding to the case-insensitive key.
@@ -140,13 +319,32 @@ entity path. All arguments named "key" is case-insensitive.
: self[ key ] = val
sets the header field corresponding to the case-insensitive key.
+: each {|name, val| .... }
+ iterates for each field name and value pair.
+
+: basic_auth( account, password )
+ set Authorization: header for basic auth.
+
+: range
+ returns a Range object which represents Range: header field.
+
+: range = r
+: set_range( i, len )
+ set Range: header from Range (arg r) or beginning index and
+ length from it (arg i&len).
+
+: content_length
+ returns a Integer object which represents Content-Length: header field.
+
+: content_range
+ returns a Range object which represents Content-Range: header field.
== class Net::HTTPResponse
HTTP response class. This class wraps response header and entity.
All arguments named KEY is case-insensitive.
-=== Methods
+=== Instance Methods
: self[ key ]
returns the header field corresponding to the case-insensitive key.
@@ -166,7 +364,7 @@ All arguments named KEY is case-insensitive.
iterates for each field name and value pair.
: canonical_each {|name,value| .... }
- iterates for each canonical field name and value pair.
+ iterates for each "canonical" field name and value pair.
: code
HTTP result code string. For example, '302'.
@@ -175,34 +373,18 @@ All arguments named KEY is case-insensitive.
HTTP result message. For example, 'Not Found'.
: read_body( dest = '' )
- gets response body and write it into DEST using "<<" method.
+ gets entity body and write it into DEST using "<<" method.
If this method is called twice or more, nothing will be done
and returns first DEST.
: read_body {|str| .... }
- gets response body little by little and pass it to block.
+ gets entity body little by little and pass it to block.
: body
- response body. If #read_body has been called, this method
- returns arg of #read_body, DEST. Else gets body as String
- and returns it.
+ response body. If #read_body has been called, this method returns
+ arg of #read_body DEST. Else gets body as String and returns it.
-== Switching Net::HTTP versions
-
-You can use Net::HTTP 1.1 features by calling HTTP.version_1_1 .
-And calling Net::HTTP.version_1_2 allows you to use 1.2 features
-again.
-
- # example
- HTTP.start {|http1| ...(http1 has 1.2 features)... }
-
- HTTP.version_1_1
- HTTP.start {|http2| ...(http2 has 1.1 features)... }
-
- HTTP.version_1_2
- HTTP.start {|http3| ...(http3 has 1.2 features)... }
-
=end
require 'net/protocol'
@@ -224,18 +406,13 @@ module Net
protocol_param :port, '80'
-
def initialize( addr = nil, port = nil )
super
- @proxy_address = nil
- @proxy_port = nil
-
@curr_http_version = HTTPVersion
@seems_1_0_server = false
end
-
private
def conn_command( sock )
@@ -255,7 +432,11 @@ module Net
class << self
def Proxy( p_addr, p_port = nil )
- ProxyMod.create_proxy_class( p_addr, p_port || self.port )
+ if p_addr then
+ ProxyMod.create_proxy_class( p_addr, p_port || self.port )
+ else
+ self
+ end
end
alias orig_new new
@@ -271,32 +452,34 @@ module Net
new( address, port, p_addr, p_port ).start( &block )
end
- def proxy_class?
- false
- end
+ @is_proxy_class = false
+ @proxy_addr = nil
+ @proxy_port = nil
- def proxy_address
- nil
+ def proxy_class?
+ @is_proxy_class
end
- def proxy_port
- nil
- end
+ attr_reader :proxy_address
+ attr_reader :proxy_port
end
def proxy?
- false
+ type.proxy?
end
def proxy_address
- nil
+ type.proxy_address
end
def proxy_port
- nil
+ type.proxy_port
end
+ alias proxyaddr proxy_address
+ alias proxyport proxy_port
+
def edit_path( path )
path
end
@@ -304,52 +487,22 @@ module Net
module ProxyMod
- class << self
-
- def create_proxy_class( p_addr, p_port )
- mod = self
- klass = Class.new( HTTP )
- klass.module_eval {
- include mod
- @proxy_address = p_addr
- @proxy_port = p_port
- }
- def klass.proxy_class?
- true
- end
-
- def klass.proxy_address
- @proxy_address
- end
-
- def klass.proxy_port
- @proxy_port
- end
-
- klass
- end
-
+ def self.create_proxy_class( p_addr, p_port )
+ mod = self
+ klass = Class.new( HTTP )
+ klass.module_eval {
+ include mod
+ @is_proxy = true
+ @proxy_address = p_addr
+ @proxy_port = p_port
+ }
+ klass
end
- def initialize( addr, port )
- super
- @proxy_address = type.proxy_address
- @proxy_port = type.proxy_port
- end
-
- attr_reader :proxy_address, :proxy_port
-
- alias proxyaddr proxy_address
- alias proxyport proxy_port
-
- def proxy?
- true
- end
-
private
def conn_socket( addr, port )
- super @proxy_address, @proxy_port
+ super proxy_address, proxy_port
end
def edit_path( path )
@@ -363,7 +516,11 @@ module Net
# for backward compatibility
#
- @@newimpl = true
+ if Version < '1.2.0' then ###noupdate
+ @@newimpl = false
+ else
+ @@newimpl = true
+ end
class << self
@@ -375,6 +532,10 @@ module Net
@@newimpl = false
end
+ def is_version_1_2?
+ @@newimpl
+ end
+
private
def setvar( obj )
@@ -662,15 +823,15 @@ 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
end
- return *arr
+ return arr
end
def range=( r, fin = nil )
@@ -906,7 +1067,10 @@ module Net
@buf.concat s
end
- alias << write
+ def <<( s )
+ @buf.concat s
+ self
+ end
def terminate
ret = @buf
@@ -1028,7 +1192,7 @@ module Net
end
def value
- SuccessCode === self or error! self
+ SuccessCode === self or error!
end
@@ -1134,4 +1298,8 @@ module Net
}
+
+ HTTPResponse = NetPrivate::HTTPResponse
+ HTTPResponseReceiver = NetPrivate::HTTPResponse
+
end # module Net