1 | =begin
|
---|
2 |
|
---|
3 | = $RCSfile$ -- SSL/TLS enhancement for Net::HTTP.
|
---|
4 |
|
---|
5 | == Info
|
---|
6 | 'OpenSSL for Ruby 2' project
|
---|
7 | Copyright (C) 2001 GOTOU Yuuzou <[email protected]>
|
---|
8 | All rights reserved.
|
---|
9 |
|
---|
10 | == Licence
|
---|
11 | This program is licenced under the same licence as Ruby.
|
---|
12 | (See the file 'LICENCE'.)
|
---|
13 |
|
---|
14 | == Requirements
|
---|
15 | This program requires Net 1.2.0 or higher version.
|
---|
16 | You can get it from RAA or Ruby's CVS repository.
|
---|
17 |
|
---|
18 | == Version
|
---|
19 | $Id: https.rb 11708 2007-02-12 23:01:19Z shyouhei $
|
---|
20 |
|
---|
21 | 2001-11-06: Contiributed to Ruby/OpenSSL project.
|
---|
22 | 2004-03-06: Some code is merged in to net/http.
|
---|
23 |
|
---|
24 | == Example
|
---|
25 |
|
---|
26 | Here is a simple HTTP client:
|
---|
27 |
|
---|
28 | require 'net/http'
|
---|
29 | require 'uri'
|
---|
30 |
|
---|
31 | uri = URI.parse(ARGV[0] || 'http://localhost/')
|
---|
32 | http = Net::HTTP.new(uri.host, uri.port)
|
---|
33 | http.start {
|
---|
34 | http.request_get(uri.path) {|res|
|
---|
35 | print res.body
|
---|
36 | }
|
---|
37 | }
|
---|
38 |
|
---|
39 | It can be replaced by the following code:
|
---|
40 |
|
---|
41 | require 'net/https'
|
---|
42 | require 'uri'
|
---|
43 |
|
---|
44 | uri = URI.parse(ARGV[0] || 'https://localhost/')
|
---|
45 | http = Net::HTTP.new(uri.host, uri.port)
|
---|
46 | http.use_ssl = true if uri.scheme == "https" # enable SSL/TLS
|
---|
47 | http.start {
|
---|
48 | http.request_get(uri.path) {|res|
|
---|
49 | print res.body
|
---|
50 | }
|
---|
51 | }
|
---|
52 |
|
---|
53 | == class Net::HTTP
|
---|
54 |
|
---|
55 | === Instance Methods
|
---|
56 |
|
---|
57 | : use_ssl?
|
---|
58 | returns true if use SSL/TLS with HTTP.
|
---|
59 |
|
---|
60 | : use_ssl=((|true_or_false|))
|
---|
61 | sets use_ssl.
|
---|
62 |
|
---|
63 | : peer_cert
|
---|
64 | return the X.509 certificates the server presented.
|
---|
65 |
|
---|
66 | : key, key=((|key|))
|
---|
67 | Sets an OpenSSL::PKey::RSA or OpenSSL::PKey::DSA object.
|
---|
68 | (This method is appeared in Michal Rokos's OpenSSL extention.)
|
---|
69 |
|
---|
70 | : cert, cert=((|cert|))
|
---|
71 | Sets an OpenSSL::X509::Certificate object as client certificate
|
---|
72 | (This method is appeared in Michal Rokos's OpenSSL extention).
|
---|
73 |
|
---|
74 | : ca_file, ca_file=((|path|))
|
---|
75 | Sets path of a CA certification file in PEM format.
|
---|
76 | The file can contrain several CA certificats.
|
---|
77 |
|
---|
78 | : ca_path, ca_path=((|path|))
|
---|
79 | Sets path of a CA certification directory containing certifications
|
---|
80 | in PEM format.
|
---|
81 |
|
---|
82 | : verify_mode, verify_mode=((|mode|))
|
---|
83 | Sets the flags for server the certification verification at
|
---|
84 | begining of SSL/TLS session.
|
---|
85 | OpenSSL::SSL::VERIFY_NONE or OpenSSL::SSL::VERIFY_PEER is acceptable.
|
---|
86 |
|
---|
87 | : verify_callback, verify_callback=((|proc|))
|
---|
88 | Sets the verify callback for the server certification verification.
|
---|
89 |
|
---|
90 | : verify_depth, verify_depth=((|num|))
|
---|
91 | Sets the maximum depth for the certificate chain verification.
|
---|
92 |
|
---|
93 | : cert_store, cert_store=((|store|))
|
---|
94 | Sets the X509::Store to verify peer certificate.
|
---|
95 |
|
---|
96 | : ssl_timeout, ssl_timeout=((|sec|))
|
---|
97 | Sets the SSL timeout seconds.
|
---|
98 |
|
---|
99 | =end
|
---|
100 |
|
---|
101 | require 'net/http'
|
---|
102 | require 'openssl'
|
---|
103 |
|
---|
104 | module Net
|
---|
105 |
|
---|
106 | class HTTP
|
---|
107 | remove_method :use_ssl?
|
---|
108 | def use_ssl?
|
---|
109 | @use_ssl
|
---|
110 | end
|
---|
111 |
|
---|
112 | # For backward compatibility.
|
---|
113 | alias use_ssl use_ssl?
|
---|
114 |
|
---|
115 | # Turn on/off SSL.
|
---|
116 | # This flag must be set before starting session.
|
---|
117 | # If you change use_ssl value after session started,
|
---|
118 | # a Net::HTTP object raises IOError.
|
---|
119 | def use_ssl=(flag)
|
---|
120 | flag = (flag ? true : false)
|
---|
121 | raise IOError, "use_ssl value changed, but session already started" \
|
---|
122 | if started? and @use_ssl != flag
|
---|
123 | if flag and not @ssl_context
|
---|
124 | @ssl_context = OpenSSL::SSL::SSLContext.new
|
---|
125 | end
|
---|
126 | @use_ssl = flag
|
---|
127 | end
|
---|
128 |
|
---|
129 | def self.ssl_context_accessor(name)
|
---|
130 | module_eval(<<-End, __FILE__, __LINE__ + 1)
|
---|
131 | def #{name}
|
---|
132 | return nil unless @ssl_context
|
---|
133 | @ssl_context.#{name}
|
---|
134 | end
|
---|
135 |
|
---|
136 | def #{name}=(val)
|
---|
137 | @ssl_context ||= OpenSSL::SSL::SSLContext.new
|
---|
138 | @ssl_context.#{name} = val
|
---|
139 | end
|
---|
140 | End
|
---|
141 | end
|
---|
142 |
|
---|
143 | ssl_context_accessor :key
|
---|
144 | ssl_context_accessor :cert
|
---|
145 | ssl_context_accessor :ca_file
|
---|
146 | ssl_context_accessor :ca_path
|
---|
147 | ssl_context_accessor :verify_mode
|
---|
148 | ssl_context_accessor :verify_callback
|
---|
149 | ssl_context_accessor :verify_depth
|
---|
150 | ssl_context_accessor :cert_store
|
---|
151 |
|
---|
152 | def ssl_timeout
|
---|
153 | return nil unless @ssl_context
|
---|
154 | @ssl_context.timeout
|
---|
155 | end
|
---|
156 |
|
---|
157 | def ssl_timeout=(sec)
|
---|
158 | raise ArgumentError, 'Net::HTTP#ssl_timeout= called but use_ssl=false' \
|
---|
159 | unless use_ssl?
|
---|
160 | @ssl_context ||= OpenSSL::SSL::SSLContext.new
|
---|
161 | @ssl_context.timeout = sec
|
---|
162 | end
|
---|
163 |
|
---|
164 | # For backward compatibility
|
---|
165 | alias timeout= ssl_timeout=
|
---|
166 |
|
---|
167 | def peer_cert
|
---|
168 | return nil if not use_ssl? or not @socket
|
---|
169 | @socket.io.peer_cert
|
---|
170 | end
|
---|
171 | end
|
---|
172 |
|
---|
173 | end
|
---|