1 | # SOAP4R - net/http wrapper
|
---|
2 | # Copyright (C) 2003 NAKAMURA, Hiroshi <[email protected]>.
|
---|
3 |
|
---|
4 | # This program is copyrighted free software by NAKAMURA, Hiroshi. You can
|
---|
5 | # redistribute it and/or modify it under the same terms of Ruby's license;
|
---|
6 | # either the dual license version in 2003, or any later version.
|
---|
7 |
|
---|
8 |
|
---|
9 | require 'net/http'
|
---|
10 |
|
---|
11 |
|
---|
12 | module SOAP
|
---|
13 |
|
---|
14 |
|
---|
15 | class NetHttpClient
|
---|
16 |
|
---|
17 | SSLEnabled = begin
|
---|
18 | require 'net/https'
|
---|
19 | true
|
---|
20 | rescue LoadError
|
---|
21 | false
|
---|
22 | end
|
---|
23 |
|
---|
24 | attr_reader :proxy
|
---|
25 | attr_accessor :no_proxy
|
---|
26 | attr_accessor :debug_dev
|
---|
27 | attr_accessor :ssl_config # ignored for now.
|
---|
28 | attr_accessor :protocol_version # ignored for now.
|
---|
29 | attr_accessor :connect_timeout
|
---|
30 | attr_accessor :send_timeout # ignored for now.
|
---|
31 | attr_accessor :receive_timeout
|
---|
32 |
|
---|
33 | def initialize(proxy = nil, agent = nil)
|
---|
34 | @proxy = proxy ? URI.parse(proxy) : nil
|
---|
35 | @agent = agent
|
---|
36 | @debug_dev = nil
|
---|
37 | @session_manager = SessionManager.new
|
---|
38 | @no_proxy = @ssl_config = @protocol_version = nil
|
---|
39 | @connect_timeout = @send_timeout = @receive_timeout = nil
|
---|
40 | end
|
---|
41 |
|
---|
42 | def test_loopback_response
|
---|
43 | raise NotImplementedError.new("not supported for now")
|
---|
44 | end
|
---|
45 |
|
---|
46 | def proxy=(proxy)
|
---|
47 | if proxy.nil?
|
---|
48 | @proxy = nil
|
---|
49 | else
|
---|
50 | if proxy.is_a?(URI)
|
---|
51 | @proxy = proxy
|
---|
52 | else
|
---|
53 | @proxy = URI.parse(proxy)
|
---|
54 | end
|
---|
55 | if @proxy.scheme == nil or @proxy.scheme.downcase != 'http' or
|
---|
56 | @proxy.host == nil or @proxy.port == nil
|
---|
57 | raise ArgumentError.new("unsupported proxy `#{proxy}'")
|
---|
58 | end
|
---|
59 | end
|
---|
60 | reset_all
|
---|
61 | @proxy
|
---|
62 | end
|
---|
63 |
|
---|
64 | def set_basic_auth(uri, user_id, passwd)
|
---|
65 | # net/http does not handle url.
|
---|
66 | @basic_auth = [user_id, passwd]
|
---|
67 | raise NotImplementedError.new("basic_auth is not supported under soap4r + net/http.")
|
---|
68 | end
|
---|
69 |
|
---|
70 | def set_cookie_store(filename)
|
---|
71 | raise NotImplementedError.new
|
---|
72 | end
|
---|
73 |
|
---|
74 | def save_cookie_store(filename)
|
---|
75 | raise NotImplementedError.new
|
---|
76 | end
|
---|
77 |
|
---|
78 | def reset(url)
|
---|
79 | # no persistent connection. ignored.
|
---|
80 | end
|
---|
81 |
|
---|
82 | def reset_all
|
---|
83 | # no persistent connection. ignored.
|
---|
84 | end
|
---|
85 |
|
---|
86 | def post(url, req_body, header = {})
|
---|
87 | unless url.is_a?(URI)
|
---|
88 | url = URI.parse(url)
|
---|
89 | end
|
---|
90 | extra = header.dup
|
---|
91 | extra['User-Agent'] = @agent if @agent
|
---|
92 | res = start(url) { |http|
|
---|
93 | http.post(url.request_uri, req_body, extra)
|
---|
94 | }
|
---|
95 | Response.new(res)
|
---|
96 | end
|
---|
97 |
|
---|
98 | def get_content(url, header = {})
|
---|
99 | unless url.is_a?(URI)
|
---|
100 | url = URI.parse(url)
|
---|
101 | end
|
---|
102 | extra = header.dup
|
---|
103 | extra['User-Agent'] = @agent if @agent
|
---|
104 | res = start(url) { |http|
|
---|
105 | http.get(url.request_uri, extra)
|
---|
106 | }
|
---|
107 | res.body
|
---|
108 | end
|
---|
109 |
|
---|
110 | private
|
---|
111 |
|
---|
112 | def start(url)
|
---|
113 | http = create_connection(url)
|
---|
114 | response = nil
|
---|
115 | http.start { |worker|
|
---|
116 | response = yield(worker)
|
---|
117 | worker.finish
|
---|
118 | }
|
---|
119 | @debug_dev << response.body if @debug_dev
|
---|
120 | response
|
---|
121 | end
|
---|
122 |
|
---|
123 | def create_connection(url)
|
---|
124 | proxy_host = proxy_port = nil
|
---|
125 | unless no_proxy?(url)
|
---|
126 | proxy_host = @proxy.host
|
---|
127 | proxy_port = @proxy.port
|
---|
128 | end
|
---|
129 | http = Net::HTTP::Proxy(proxy_host, proxy_port).new(url.host, url.port)
|
---|
130 | if http.respond_to?(:set_debug_output)
|
---|
131 | http.set_debug_output(@debug_dev)
|
---|
132 | end
|
---|
133 | http.open_timeout = @connect_timeout if @connect_timeout
|
---|
134 | http.read_timeout = @receive_timeout if @receive_timeout
|
---|
135 | case url
|
---|
136 | when URI::HTTPS
|
---|
137 | if SSLEnabled
|
---|
138 | http.use_ssl = true
|
---|
139 | else
|
---|
140 | raise RuntimeError.new("Cannot connect to #{url} (OpenSSL is not installed.)")
|
---|
141 | end
|
---|
142 | when URI::HTTP
|
---|
143 | # OK
|
---|
144 | else
|
---|
145 | raise RuntimeError.new("Cannot connect to #{url} (Not HTTP.)")
|
---|
146 | end
|
---|
147 | http
|
---|
148 | end
|
---|
149 |
|
---|
150 | NO_PROXY_HOSTS = ['localhost']
|
---|
151 |
|
---|
152 | def no_proxy?(uri)
|
---|
153 | if !@proxy or NO_PROXY_HOSTS.include?(uri.host)
|
---|
154 | return true
|
---|
155 | end
|
---|
156 | if @no_proxy
|
---|
157 | @no_proxy.scan(/([^:,]*)(?::(\d+))?/) do |host, port|
|
---|
158 | if /(\A|\.)#{Regexp.quote(host)}\z/i =~ uri.host &&
|
---|
159 | (!port || uri.port == port.to_i)
|
---|
160 | return true
|
---|
161 | end
|
---|
162 | end
|
---|
163 | else
|
---|
164 | false
|
---|
165 | end
|
---|
166 | end
|
---|
167 |
|
---|
168 | class SessionManager
|
---|
169 | attr_accessor :connect_timeout
|
---|
170 | attr_accessor :send_timeout
|
---|
171 | attr_accessor :receive_timeout
|
---|
172 | end
|
---|
173 |
|
---|
174 | class Response
|
---|
175 | attr_reader :content
|
---|
176 | attr_reader :status
|
---|
177 | attr_reader :reason
|
---|
178 | attr_reader :contenttype
|
---|
179 |
|
---|
180 | def initialize(res)
|
---|
181 | @status = res.code.to_i
|
---|
182 | @reason = res.message
|
---|
183 | @contenttype = res['content-type']
|
---|
184 | @content = res.body
|
---|
185 | end
|
---|
186 | end
|
---|
187 | end
|
---|
188 |
|
---|
189 |
|
---|
190 | end
|
---|