http2 0.0.24 → 0.0.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +1 -3
- data/Gemfile.lock +25 -19
- data/README.md +1 -0
- data/VERSION +1 -1
- data/http2.gemspec +16 -8
- data/include/connection.rb +142 -0
- data/include/get_request.rb +34 -0
- data/include/post_data_generator.rb +62 -0
- data/include/post_multipart_request.rb +113 -0
- data/include/post_request.rb +71 -0
- data/include/response.rb +17 -45
- data/include/response_reader.rb +101 -97
- data/include/url_builder.rb +58 -0
- data/lib/http2.rb +52 -315
- data/spec/http2/post_data_generator_spec.rb +24 -0
- data/spec/http2/url_builder_spec.rb +17 -0
- data/spec/http2_spec.rb +18 -24
- data/spec/spec_helper.rb +3 -1
- metadata +25 -18
- data/include/post_multipart_helper.rb +0 -77
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
class Http2::UrlBuilder
|
|
2
|
+
attr_accessor :host, :port, :protocol, :path, :params
|
|
3
|
+
|
|
4
|
+
def initialize args = {}
|
|
5
|
+
@params = {}
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def build_params
|
|
9
|
+
url_params = ""
|
|
10
|
+
|
|
11
|
+
if !params.empty?
|
|
12
|
+
first = true
|
|
13
|
+
|
|
14
|
+
params.each do |key, val|
|
|
15
|
+
if first
|
|
16
|
+
first = false
|
|
17
|
+
else
|
|
18
|
+
url_params << "&"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
url_params << Http2::Utils.urlenc(key)
|
|
22
|
+
url_params << "="
|
|
23
|
+
url_params << Http2::Utils.urlenc(val)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
return url_params
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def build_path_and_params
|
|
31
|
+
url = "#{path}"
|
|
32
|
+
|
|
33
|
+
if params?
|
|
34
|
+
url << "?"
|
|
35
|
+
url << build_params
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
return url
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def build
|
|
42
|
+
url = ""
|
|
43
|
+
url << "#{protocol}://" if protocol
|
|
44
|
+
|
|
45
|
+
if host
|
|
46
|
+
url << host
|
|
47
|
+
url << ":#{port}/" if port
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
url << build_path_and_params
|
|
51
|
+
|
|
52
|
+
return url
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def params?
|
|
56
|
+
@params.any?
|
|
57
|
+
end
|
|
58
|
+
end
|
data/lib/http2.rb
CHANGED
|
@@ -29,15 +29,17 @@ class Http2
|
|
|
29
29
|
end
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
-
attr_reader :cookies, :args, :resp, :raise_errors, :nl
|
|
32
|
+
attr_reader :autostate, :connection, :cookies, :args, :debug, :mutex, :resp, :raise_errors, :nl
|
|
33
|
+
attr_accessor :keepalive_max, :keepalive_timeout
|
|
33
34
|
|
|
34
|
-
VALID_ARGUMENTS_INITIALIZE = [:host, :port, :ssl, :nl, :user_agent, :raise_errors, :follow_redirects, :debug, :encoding_gzip, :autostate, :basic_auth, :extra_headers, :proxy]
|
|
35
|
+
VALID_ARGUMENTS_INITIALIZE = [:host, :port, :skip_port_in_host_header, :ssl, :nl, :user_agent, :raise_errors, :follow_redirects, :debug, :encoding_gzip, :autostate, :basic_auth, :extra_headers, :proxy]
|
|
35
36
|
def initialize(args = {})
|
|
36
37
|
@args = parse_init_args(args)
|
|
37
38
|
set_default_values
|
|
38
39
|
@cookies = {}
|
|
39
40
|
@mutex = Monitor.new
|
|
40
|
-
|
|
41
|
+
|
|
42
|
+
@connection = ::Http2::Connection.new(self)
|
|
41
43
|
|
|
42
44
|
if block_given?
|
|
43
45
|
begin
|
|
@@ -48,35 +50,11 @@ class Http2
|
|
|
48
50
|
end
|
|
49
51
|
end
|
|
50
52
|
|
|
51
|
-
#Closes current connection if any, changes the arguments on the object and reconnects keeping all cookies and other stuff intact.
|
|
53
|
+
# Closes current connection if any, changes the arguments on the object and reconnects keeping all cookies and other stuff intact.
|
|
52
54
|
def change(args)
|
|
53
|
-
self.close
|
|
54
55
|
@args.merge!(args)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
#Closes the current connection if any.
|
|
59
|
-
def close
|
|
60
|
-
@sock.close if @sock and !@sock.closed?
|
|
61
|
-
@sock_ssl.close if @sock_ssl and !@sock_ssl.closed?
|
|
62
|
-
@sock_plain.close if @sock_plain and !@sock_plain.closed?
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
#Returns boolean based on the if the object is connected and the socket is working.
|
|
66
|
-
#===Examples
|
|
67
|
-
# puts "Socket is working." if http.socket_working?
|
|
68
|
-
def socket_working?
|
|
69
|
-
return false if !@sock or @sock.closed?
|
|
70
|
-
|
|
71
|
-
if @keepalive_timeout and @request_last
|
|
72
|
-
between = Time.now.to_i - @request_last.to_i
|
|
73
|
-
if between >= @keepalive_timeout
|
|
74
|
-
puts "Http2: We are over the keepalive-wait - returning false for socket_working?." if @debug
|
|
75
|
-
return false
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
return true
|
|
56
|
+
@connection.destroy
|
|
57
|
+
@connection = ::Http2::Connection.new(self)
|
|
80
58
|
end
|
|
81
59
|
|
|
82
60
|
#Destroys the object unsetting all variables and closing all sockets.
|
|
@@ -91,53 +69,24 @@ class Http2
|
|
|
91
69
|
@keepalive_timeout = nil
|
|
92
70
|
@request_last = nil
|
|
93
71
|
|
|
94
|
-
@
|
|
95
|
-
@
|
|
96
|
-
|
|
97
|
-
@sock_plain.close if @sock_plain and !@sock_plain.closed?
|
|
98
|
-
@sock_plain = nil
|
|
99
|
-
|
|
100
|
-
@sock_ssl.close if @sock_ssl and !@sock_ssl.closed?
|
|
101
|
-
@sock_ssl = nil
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
#Reconnects to the host.
|
|
105
|
-
def reconnect
|
|
106
|
-
puts "Http2: Reconnect." if @debug
|
|
107
|
-
|
|
108
|
-
#Open connection.
|
|
109
|
-
if @args[:proxy] && @args[:ssl]
|
|
110
|
-
connect_proxy_ssl
|
|
111
|
-
elsif @args[:proxy]
|
|
112
|
-
connect_proxy
|
|
113
|
-
else
|
|
114
|
-
print "Http2: Opening socket connection to '#{@args[:host]}:#{@args[:port]}'.\n" if @debug
|
|
115
|
-
@sock_plain = TCPSocket.new(@args[:host], @args[:port].to_i)
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
if @args[:ssl]
|
|
119
|
-
apply_ssl
|
|
120
|
-
else
|
|
121
|
-
@sock = @sock_plain
|
|
122
|
-
end
|
|
72
|
+
@connection.destroy
|
|
73
|
+
@connection = nil
|
|
123
74
|
end
|
|
124
75
|
|
|
125
76
|
#Forces various stuff into arguments-hash like URL from original arguments and enables single-string-shortcuts and more.
|
|
126
77
|
def parse_args(*args)
|
|
127
|
-
if args.length == 1
|
|
78
|
+
if args.length == 1 && args.first.is_a?(String)
|
|
128
79
|
args = {:url => args.first}
|
|
129
80
|
elsif args.length >= 2
|
|
130
81
|
raise "Couldnt parse arguments."
|
|
131
|
-
elsif args.is_a?(Array)
|
|
82
|
+
elsif args.is_a?(Array) && args.length == 1
|
|
132
83
|
args = args.first
|
|
133
84
|
else
|
|
134
85
|
raise "Invalid arguments: '#{args.class.name}'."
|
|
135
86
|
end
|
|
136
87
|
|
|
137
|
-
if
|
|
138
|
-
raise "
|
|
139
|
-
elsif args[:url].to_s.split("\n").length > 1
|
|
140
|
-
raise "Multiple lines given in URL: '#{args[:url]}'."
|
|
88
|
+
if args[:url].to_s.split("\n").length != 1
|
|
89
|
+
raise "Invalid URL: '#{args[:url]}'."
|
|
141
90
|
end
|
|
142
91
|
|
|
143
92
|
return args
|
|
@@ -148,58 +97,18 @@ class Http2
|
|
|
148
97
|
# res = http.get("somepage.html")
|
|
149
98
|
# print res.body #=> <String>-object containing the HTML gotten.
|
|
150
99
|
def get(args)
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
if args.key?(:method) && args[:method]
|
|
154
|
-
method = args[:method].to_s.upcase
|
|
155
|
-
else
|
|
156
|
-
method = "GET"
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
header_str = "#{method} /#{args[:url]} HTTP/1.1#{@nl}"
|
|
160
|
-
header_str << self.header_str(self.default_headers(args), args)
|
|
161
|
-
header_str << @nl
|
|
162
|
-
|
|
163
|
-
@mutex.synchronize do
|
|
164
|
-
print "Http2: Writing headers.\n" if @debug
|
|
165
|
-
print "Header str: #{header_str}\n" if @debug
|
|
166
|
-
self.write(header_str)
|
|
167
|
-
|
|
168
|
-
print "Http2: Reading response.\n" if @debug
|
|
169
|
-
resp = self.read_response(args)
|
|
170
|
-
|
|
171
|
-
print "Http2: Done with get request.\n" if @debug
|
|
172
|
-
return resp
|
|
173
|
-
end
|
|
100
|
+
::Http2::GetRequest.new(self, args).execute
|
|
174
101
|
end
|
|
175
102
|
|
|
176
103
|
# Proxies the request to another method but forces the method to be "DELETE".
|
|
177
104
|
def delete(args)
|
|
178
105
|
if args[:json]
|
|
179
|
-
return
|
|
106
|
+
return post(args.merge(:method => :delete))
|
|
180
107
|
else
|
|
181
|
-
return
|
|
108
|
+
return get(args.merge(:method => :delete))
|
|
182
109
|
end
|
|
183
110
|
end
|
|
184
111
|
|
|
185
|
-
#Tries to write a string to the socket. If it fails it reconnects and tries again.
|
|
186
|
-
def write(str)
|
|
187
|
-
#Reset variables.
|
|
188
|
-
@length = nil
|
|
189
|
-
@encoding = nil
|
|
190
|
-
self.reconnect if !self.socket_working?
|
|
191
|
-
|
|
192
|
-
begin
|
|
193
|
-
raise Errno::EPIPE, "The socket is closed." if !@sock or @sock.closed?
|
|
194
|
-
self.sock_write(str)
|
|
195
|
-
rescue Errno::EPIPE #this can also be thrown by puts.
|
|
196
|
-
self.reconnect
|
|
197
|
-
self.sock_write(str)
|
|
198
|
-
end
|
|
199
|
-
|
|
200
|
-
@request_last = Time.now
|
|
201
|
-
end
|
|
202
|
-
|
|
203
112
|
#Returns the default headers for a request.
|
|
204
113
|
#===Examples
|
|
205
114
|
# headers_hash = http.default_headers
|
|
@@ -213,192 +122,40 @@ class Http2
|
|
|
213
122
|
}
|
|
214
123
|
|
|
215
124
|
#Possible to give custom host-argument.
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
headers["Host"] += ":#{_args[:port]}" unless _args[:port] && [80,443].include?(_args[:port].to_i)
|
|
125
|
+
host = args[:host] || @args[:host]
|
|
126
|
+
port = args[:port] || @args[:port]
|
|
219
127
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
128
|
+
headers["Host"] = host
|
|
129
|
+
headers["Host"] << ":#{port}" if port && ![80, 443].include?(port.to_i) && !@args[:skip_port_in_host_header]
|
|
130
|
+
headers["Accept-Encoding"] = "gzip" if @args[:encoding_gzip]
|
|
223
131
|
|
|
224
132
|
if @args[:basic_auth]
|
|
225
133
|
require "base64" unless ::Kernel.const_defined?(:Base64)
|
|
226
134
|
headers["Authorization"] = "Basic #{Base64.encode64("#{@args[:basic_auth][:user]}:#{@args[:basic_auth][:passwd]}").strip}"
|
|
227
135
|
end
|
|
228
136
|
|
|
229
|
-
if @args[:extra_headers]
|
|
230
|
-
|
|
231
|
-
end
|
|
232
|
-
|
|
233
|
-
if args[:headers]
|
|
234
|
-
headers.merge!(args[:headers])
|
|
235
|
-
end
|
|
236
|
-
|
|
137
|
+
headers.merge!(@args[:extra_headers]) if @args[:extra_headers]
|
|
138
|
+
headers.merge!(args[:headers]) if args[:headers]
|
|
237
139
|
return headers
|
|
238
140
|
end
|
|
239
141
|
|
|
240
|
-
#This is used to convert a hash to valid post-data recursivly.
|
|
241
|
-
def self.post_convert_data(pdata, args = nil)
|
|
242
|
-
praw = ""
|
|
243
|
-
|
|
244
|
-
if pdata.is_a?(Hash)
|
|
245
|
-
pdata.each do |key, val|
|
|
246
|
-
praw << "&" if praw != ""
|
|
247
|
-
|
|
248
|
-
if args and args[:orig_key]
|
|
249
|
-
key = "#{args[:orig_key]}[#{key}]"
|
|
250
|
-
end
|
|
251
|
-
|
|
252
|
-
if val.is_a?(Hash) or val.is_a?(Array)
|
|
253
|
-
praw << self.post_convert_data(val, {:orig_key => key})
|
|
254
|
-
else
|
|
255
|
-
praw << "#{Http2::Utils.urlenc(key)}=#{Http2::Utils.urlenc(Http2.post_convert_data(val))}"
|
|
256
|
-
end
|
|
257
|
-
end
|
|
258
|
-
elsif pdata.is_a?(Array)
|
|
259
|
-
count = 0
|
|
260
|
-
pdata.each do |val|
|
|
261
|
-
praw << "&" if praw != ""
|
|
262
|
-
|
|
263
|
-
if args and args[:orig_key]
|
|
264
|
-
key = "#{args[:orig_key]}[#{count}]"
|
|
265
|
-
else
|
|
266
|
-
key = count
|
|
267
|
-
end
|
|
268
|
-
|
|
269
|
-
if val.is_a?(Hash) or val.is_a?(Array)
|
|
270
|
-
praw << self.post_convert_data(val, {:orig_key => key})
|
|
271
|
-
else
|
|
272
|
-
praw << "#{Http2::Utils.urlenc(key)}=#{Http2::Utils.urlenc(Http2.post_convert_data(val))}"
|
|
273
|
-
end
|
|
274
|
-
|
|
275
|
-
count += 1
|
|
276
|
-
end
|
|
277
|
-
else
|
|
278
|
-
return pdata.to_s
|
|
279
|
-
end
|
|
280
|
-
|
|
281
|
-
return praw
|
|
282
|
-
end
|
|
283
|
-
|
|
284
|
-
VALID_ARGUMENTS_POST = [:post, :url, :default_headers, :headers, :json, :method, :cookies, :on_content, :content_type]
|
|
285
142
|
#Posts to a certain page.
|
|
286
143
|
#===Examples
|
|
287
144
|
# res = http.post("login.php", {"username" => "John Doe", "password" => 123)
|
|
288
145
|
def post(args)
|
|
289
|
-
|
|
290
|
-
raise "Invalid key: '#{key}'." unless VALID_ARGUMENTS_POST.include?(key)
|
|
291
|
-
end
|
|
292
|
-
|
|
293
|
-
args = self.parse_args(args)
|
|
294
|
-
|
|
295
|
-
if args.key?(:method) && args[:method]
|
|
296
|
-
method = args[:method].to_s.upcase
|
|
297
|
-
else
|
|
298
|
-
method = "POST"
|
|
299
|
-
end
|
|
300
|
-
|
|
301
|
-
if args[:json]
|
|
302
|
-
require "json" unless ::Kernel.const_defined?(:JSON)
|
|
303
|
-
praw = args[:json].to_json
|
|
304
|
-
content_type = "application/json"
|
|
305
|
-
elsif args[:post].is_a?(String)
|
|
306
|
-
praw = args[:post]
|
|
307
|
-
else
|
|
308
|
-
phash = args[:post] ? args[:post].clone : {}
|
|
309
|
-
autostate_set_on_post_hash(phash) if @args[:autostate]
|
|
310
|
-
praw = Http2.post_convert_data(phash)
|
|
311
|
-
end
|
|
312
|
-
|
|
313
|
-
content_type = args[:content_type] || content_type || "application/x-www-form-urlencoded"
|
|
314
|
-
|
|
315
|
-
@mutex.synchronize do
|
|
316
|
-
puts "Http2: Doing post." if @debug
|
|
317
|
-
|
|
318
|
-
header_str = "#{method} /#{args[:url]} HTTP/1.1#{@nl}"
|
|
319
|
-
header_str << self.header_str({"Content-Length" => praw.bytesize, "Content-Type" => content_type}.merge(self.default_headers(args)), args)
|
|
320
|
-
header_str << @nl
|
|
321
|
-
header_str << praw
|
|
322
|
-
|
|
323
|
-
puts "Http2: Header str: #{header_str}" if @debug
|
|
324
|
-
|
|
325
|
-
self.write(header_str)
|
|
326
|
-
return self.read_response(args)
|
|
327
|
-
end
|
|
146
|
+
::Http2::PostRequest.new(self, args).execute
|
|
328
147
|
end
|
|
329
148
|
|
|
330
149
|
#Posts to a certain page using the multipart-method.
|
|
331
150
|
#===Examples
|
|
332
151
|
# res = http.post_multipart("upload.php", {"normal_value" => 123, "file" => Tempfile.new(?)})
|
|
333
152
|
def post_multipart(*args)
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
phash = args[:post].clone
|
|
337
|
-
autostate_set_on_post_hash(phash) if @args[:autostate]
|
|
338
|
-
|
|
339
|
-
post_multipart_helper = ::Http2::PostMultipartHelper.new(self)
|
|
340
|
-
|
|
341
|
-
#Use tempfile to store contents to avoid eating memory if posting something really big.
|
|
342
|
-
post_multipart_helper.generate_raw(phash) do |helper, praw|
|
|
343
|
-
#Generate header-string containing 'praw'-variable.
|
|
344
|
-
header_str = "POST /#{args[:url]} HTTP/1.1#{@nl}"
|
|
345
|
-
header_str << header_str(default_headers(args).merge(
|
|
346
|
-
"Content-Type" => "multipart/form-data; boundary=#{helper.boundary}",
|
|
347
|
-
"Content-Length" => praw.size
|
|
348
|
-
), args)
|
|
349
|
-
header_str << @nl
|
|
350
|
-
|
|
351
|
-
print "Http2: Headerstr: #{header_str}\n" if @debug
|
|
352
|
-
|
|
353
|
-
#Write and return.
|
|
354
|
-
@mutex.synchronize do
|
|
355
|
-
write(header_str)
|
|
356
|
-
|
|
357
|
-
praw.rewind
|
|
358
|
-
praw.each_line do |data|
|
|
359
|
-
sock_write(data)
|
|
360
|
-
end
|
|
361
|
-
|
|
362
|
-
return read_response(args)
|
|
363
|
-
end
|
|
364
|
-
end
|
|
365
|
-
end
|
|
366
|
-
|
|
367
|
-
def sock_write(str)
|
|
368
|
-
str = str.to_s
|
|
369
|
-
return nil if str.empty?
|
|
370
|
-
count = @sock.write(str)
|
|
371
|
-
raise "Couldnt write to socket: '#{count}', '#{str}'." if count <= 0
|
|
372
|
-
end
|
|
373
|
-
|
|
374
|
-
def sock_puts(str)
|
|
375
|
-
self.sock_write("#{str}#{@nl}")
|
|
153
|
+
::Http2::PostMultipartRequest.new(self, *args).execute
|
|
376
154
|
end
|
|
377
155
|
|
|
378
156
|
#Returns a header-string which normally would be used for a request in the given state.
|
|
379
157
|
def header_str(headers_hash, args = {})
|
|
380
|
-
|
|
381
|
-
cstr = ""
|
|
382
|
-
|
|
383
|
-
first = true
|
|
384
|
-
@cookies.each do |cookie_name, cookie_data|
|
|
385
|
-
cstr << "; " if !first
|
|
386
|
-
first = false if first
|
|
387
|
-
|
|
388
|
-
if cookie_data.is_a?(Hash)
|
|
389
|
-
name = cookie_data["name"]
|
|
390
|
-
value = cookie_data["value"]
|
|
391
|
-
else
|
|
392
|
-
name = cookie_name
|
|
393
|
-
value = cookie_data
|
|
394
|
-
end
|
|
395
|
-
|
|
396
|
-
raise "Unexpected lines: #{value.lines.to_a.length}." if value.lines.to_a.length != 1
|
|
397
|
-
cstr << "#{Http2::Utils.urlenc(name)}=#{Http2::Utils.urlenc(value)}"
|
|
398
|
-
end
|
|
399
|
-
|
|
400
|
-
headers_hash["Cookie"] = cstr
|
|
401
|
-
end
|
|
158
|
+
headers_hash["Cookie"] = cookie_header_string
|
|
402
159
|
|
|
403
160
|
headers_str = ""
|
|
404
161
|
headers_hash.each do |key, val|
|
|
@@ -408,6 +165,29 @@ class Http2
|
|
|
408
165
|
return headers_str
|
|
409
166
|
end
|
|
410
167
|
|
|
168
|
+
def cookie_header_string
|
|
169
|
+
cstr = ""
|
|
170
|
+
|
|
171
|
+
first = true
|
|
172
|
+
@cookies.each do |cookie_name, cookie_data|
|
|
173
|
+
cstr << "; " unless first
|
|
174
|
+
first = false if first
|
|
175
|
+
|
|
176
|
+
if cookie_data.is_a?(Hash)
|
|
177
|
+
name = cookie_data["name"]
|
|
178
|
+
value = cookie_data["value"]
|
|
179
|
+
else
|
|
180
|
+
name = cookie_name
|
|
181
|
+
value = cookie_data
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
raise "Unexpected lines: #{value.lines.to_a.length}." if value.lines.to_a.length != 1
|
|
185
|
+
cstr << "#{Http2::Utils.urlenc(name)}=#{Http2::Utils.urlenc(value)}"
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
return cstr
|
|
189
|
+
end
|
|
190
|
+
|
|
411
191
|
def on_content_call(args, str)
|
|
412
192
|
args[:on_content].call(str) if args.key?(:on_content)
|
|
413
193
|
end
|
|
@@ -416,12 +196,7 @@ class Http2
|
|
|
416
196
|
#===Examples
|
|
417
197
|
# res = http.read_response
|
|
418
198
|
def read_response(args = {})
|
|
419
|
-
Http2::ResponseReader.new(
|
|
420
|
-
http2: self,
|
|
421
|
-
sock: @sock,
|
|
422
|
-
args: args,
|
|
423
|
-
debug: @debug
|
|
424
|
-
).response
|
|
199
|
+
::Http2::ResponseReader.new(http2: self, sock: @sock, args: args).response
|
|
425
200
|
end
|
|
426
201
|
|
|
427
202
|
private
|
|
@@ -462,7 +237,7 @@ private
|
|
|
462
237
|
|
|
463
238
|
def set_default_values
|
|
464
239
|
@debug = @args[:debug]
|
|
465
|
-
@autostate_values = {} if
|
|
240
|
+
@autostate_values = {} if autostate
|
|
466
241
|
@nl = @args[:nl] || "\r\n"
|
|
467
242
|
|
|
468
243
|
if !@args[:port]
|
|
@@ -485,42 +260,4 @@ private
|
|
|
485
260
|
@raise_errors = false
|
|
486
261
|
end
|
|
487
262
|
end
|
|
488
|
-
|
|
489
|
-
def connect_proxy_ssl
|
|
490
|
-
print "Http2: Initializing proxy stuff.\n" if @debug
|
|
491
|
-
@sock_plain = TCPSocket.new(@args[:proxy][:host], @args[:proxy][:port])
|
|
492
|
-
|
|
493
|
-
@sock_plain.write("CONNECT #{@args[:host]}:#{@args[:port]} HTTP/1.0#{@nl}")
|
|
494
|
-
@sock_plain.write("User-Agent: #{@uagent}#{@nl}")
|
|
495
|
-
|
|
496
|
-
if @args[:proxy][:user] and @args[:proxy][:passwd]
|
|
497
|
-
credential = ["#{@args[:proxy][:user]}:#{@args[:proxy][:passwd]}"].pack("m")
|
|
498
|
-
credential.delete!("\r\n")
|
|
499
|
-
@sock_plain.write("Proxy-Authorization: Basic #{credential}#{@nl}")
|
|
500
|
-
end
|
|
501
|
-
|
|
502
|
-
@sock_plain.write(@nl)
|
|
503
|
-
|
|
504
|
-
res = @sock_plain.gets
|
|
505
|
-
raise res if res.to_s.downcase != "http/1.0 200 connection established#{@nl}"
|
|
506
|
-
end
|
|
507
|
-
|
|
508
|
-
def connect_proxy
|
|
509
|
-
puts "Http2: Opening socket connection to '#{@args[:host]}:#{@args[:port]}' through proxy '#{@args[:proxy][:host]}:#{@args[:proxy][:port]}'." if @debug
|
|
510
|
-
@sock_plain = TCPSocket.new(@args[:proxy][:host], @args[:proxy][:port].to_i)
|
|
511
|
-
end
|
|
512
|
-
|
|
513
|
-
def apply_ssl
|
|
514
|
-
puts "Http2: Initializing SSL." if @debug
|
|
515
|
-
require "openssl" unless ::Kernel.const_defined?(:OpenSSL)
|
|
516
|
-
|
|
517
|
-
ssl_context = OpenSSL::SSL::SSLContext.new
|
|
518
|
-
#ssl_context.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
|
519
|
-
|
|
520
|
-
@sock_ssl = OpenSSL::SSL::SSLSocket.new(@sock_plain, ssl_context)
|
|
521
|
-
@sock_ssl.sync_close = true
|
|
522
|
-
@sock_ssl.connect
|
|
523
|
-
|
|
524
|
-
@sock = @sock_ssl
|
|
525
|
-
end
|
|
526
263
|
end
|