http2 0.0.31 → 0.0.32

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 00dd7c4f177f2a7c84ef8f9ef463fe6f2675a400
4
- data.tar.gz: 7c28395bf02c20a50d2b8633e6ddd8156c8972f3
3
+ metadata.gz: 5a6f33cdd27db12f717a7364f0b01e003fa136f4
4
+ data.tar.gz: e5db49475ea7e1d94d3637273098d3e5fa3c40ba
5
5
  SHA512:
6
- metadata.gz: bdc915bf5453cb50d0d58e298f661b833d5086f370d66bfda2e5f654d01572ea4880f340d99dd3e6853abfd20e6d3a7bed5892758add2ad4c7187087f71e59b4
7
- data.tar.gz: 54923d3a26cfe73698df0fbde92cd1dd517b61efaad45e77102fb469716d3efc4833b337bb2d915fb367d826e6370b5e068e6175a8ea7884b6b14bc9069f3024
6
+ metadata.gz: d1502af03635d87d6c13253a5f160fb697cf83f5489a99e0b2de1ed7ce3a59b38cc11c970a4848fedc8ab6ddb88c24af31d2d651360b3081ee23a12bf6700770
7
+ data.tar.gz: f4ac8597f0752a57342e0166a1bf017fc1f320d1eda7b093e7706eec8320827a5f895b320fc6bfe9e55b19dee6e58a59c62a0710a90b9cc0a177be1d5176b5f2
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- [![Build Status](https://api.shippable.com/projects/540e7b9b3479c5ea8f9ec21d/badge?branchName=master)](https://app.shippable.com/projects/540e7b9b3479c5ea8f9ec21d/builds/latest)
1
+ [![Build Status](https://img.shields.io/shippable/540e7b9b3479c5ea8f9ec21d.svg)](https://app.shippable.com/projects/540e7b9b3479c5ea8f9ec21d/builds/latest)
2
2
  [![Code Climate](https://codeclimate.com/github/kaspernj/http2.png)](https://codeclimate.com/github/kaspernj/http2)
3
3
  [![Code Climate](https://codeclimate.com/github/kaspernj/http2/coverage.png)](https://codeclimate.com/github/kaspernj/http2)
4
4
 
@@ -36,6 +36,11 @@ You can also use SSL:
36
36
  Http2.new(host: "myhost.com", ssl: true, ssl_skip_verify: true)
37
37
  ```
38
38
 
39
+ You can make it follow redirects like this:
40
+ ```ruby
41
+ Http2.new(host: "myhost.com", follow_redirects: true)
42
+ ```
43
+
39
44
  ## Get requests
40
45
  ```ruby
41
46
  res = http.get("path/to/something")
@@ -155,6 +160,14 @@ http = Http2.new(
155
160
  )
156
161
  ```
157
162
 
163
+ ## Inspect the headers that were sent
164
+
165
+ ```ruby
166
+ response = http.get("some_page")
167
+ request = response.request
168
+ request.headers_string #=> "GET /some_page\n..."
169
+ ```
170
+
158
171
  ## Contributing to http2
159
172
 
160
173
  * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
data/Rakefile CHANGED
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
- require 'rubygems'
4
- require 'bundler'
3
+ require "rubygems"
4
+ require "bundler"
5
5
  begin
6
6
  Bundler.setup(:default, :development)
7
7
  rescue Bundler::BundlerError => e
@@ -9,29 +9,32 @@ rescue Bundler::BundlerError => e
9
9
  $stderr.puts "Run `bundle install` to install missing gems"
10
10
  exit e.status_code
11
11
  end
12
- require 'rake'
12
+ require "rake"
13
13
 
14
- require 'rspec/core'
15
- require 'rspec/core/rake_task'
14
+ require "rspec/core"
15
+ require "rspec/core/rake_task"
16
16
  RSpec::Core::RakeTask.new(:spec) do |spec|
17
- spec.pattern = FileList['spec/**/*_spec.rb']
17
+ spec.pattern = FileList["spec/**/*_spec.rb"]
18
18
  end
19
19
 
20
20
  RSpec::Core::RakeTask.new(:rcov) do |spec|
21
- spec.pattern = 'spec/**/*_spec.rb'
21
+ spec.pattern = "spec/**/*_spec.rb"
22
22
  spec.rcov = true
23
23
  end
24
24
 
25
- task :default => :spec
25
+ task default: :spec
26
26
 
27
- require 'rdoc/task'
27
+ require "rdoc/task"
28
28
  Rake::RDocTask.new do |rdoc|
29
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
29
+ version = File.exist?("VERSION") ? File.read("VERSION") : ""
30
30
 
31
- rdoc.rdoc_dir = 'rdoc'
31
+ rdoc.rdoc_dir = "rdoc"
32
32
  rdoc.title = "http2 #{version}"
33
- rdoc.rdoc_files.include('README*')
34
- rdoc.rdoc_files.include('lib/**/*.rb')
33
+ rdoc.rdoc_files.include("README*")
34
+ rdoc.rdoc_files.include("lib/**/*.rb")
35
35
  end
36
36
 
37
37
  Bundler::GemHelper.install_tasks
38
+
39
+ require "best_practice_project"
40
+ BestPracticeProject.load_tasks
@@ -3,7 +3,7 @@ require "uri"
3
3
  require "monitor" unless ::Kernel.const_defined?(:Monitor)
4
4
  require "string-cases"
5
5
 
6
- #This class tries to emulate a browser in Ruby without any visual stuff. Remember cookies, keep sessions alive, reset connections according to keep-alive rules and more.
6
+ # This class tries to emulate a browser in Ruby without any visual stuff. Remember cookies, keep sessions alive, reset connections according to keep-alive rules and more.
7
7
  #===Examples
8
8
  # Http2.new(host: "www.somedomain.com", port: 80, ssl: false, debug: false) do |http|
9
9
  # res = http.get("index.rhtml?show=some_page")
@@ -17,8 +17,8 @@ require "string-cases"
17
17
  class Http2
18
18
  # Autoloader for subclasses.
19
19
  def self.const_missing(name)
20
- require "#{File.dirname(__FILE__)}/../include/#{::StringCases.camel_to_snake(name)}.rb"
21
- return Http2.const_get(name)
20
+ require "#{File.dirname(__FILE__)}/http2/#{::StringCases.camel_to_snake(name)}.rb"
21
+ Http2.const_get(name)
22
22
  end
23
23
 
24
24
  # Converts a URL to "is.gd"-short-URL.
@@ -45,17 +45,21 @@ class Http2
45
45
  begin
46
46
  yield(self)
47
47
  ensure
48
- self.destroy
48
+ destroy
49
49
  end
50
50
  end
51
51
  end
52
52
 
53
53
  def host
54
- @args[:host]
54
+ @args.fetch(:host)
55
55
  end
56
56
 
57
57
  def port
58
- @args[:port]
58
+ @args.fetch(:port)
59
+ end
60
+
61
+ def ssl?
62
+ @args[:ssl] ? true : false
59
63
  end
60
64
 
61
65
  def reconnect
@@ -68,7 +72,7 @@ class Http2
68
72
  builder.port = port
69
73
  builder.protocol = @args[:protocol]
70
74
 
71
- return builder
75
+ builder
72
76
  end
73
77
 
74
78
  # Closes current connection if any, changes the arguments on the object and reconnects keeping all cookies and other stuff intact.
@@ -104,9 +108,9 @@ class Http2
104
108
  raise "Invalid arguments: '#{args.class.name}'"
105
109
  end
106
110
 
107
- raise "Invalid URL: '#{args[:url]}'" unless args[:url].to_s.split("\n").length == 1
111
+ raise "Invalid URL: '#{args[:url]}'" if args[:url] != "" && args[:url].to_s.split("\n").length != 1
108
112
 
109
- return args
113
+ args
110
114
  end
111
115
 
112
116
  # Returns a result-object based on the arguments.
@@ -154,7 +158,7 @@ class Http2
154
158
 
155
159
  headers.merge!(@args[:extra_headers]) if @args[:extra_headers]
156
160
  headers.merge!(args[:headers]) if args[:headers]
157
- return headers
161
+ headers
158
162
  end
159
163
 
160
164
  # Posts to a certain page.
@@ -172,7 +176,7 @@ class Http2
172
176
  end
173
177
 
174
178
  # Returns a header-string which normally would be used for a request in the given state.
175
- def header_str(headers_hash, args = {})
179
+ def header_str(headers_hash)
176
180
  headers_hash["Cookie"] = cookie_header_string
177
181
 
178
182
  headers_str = ""
@@ -180,21 +184,21 @@ class Http2
180
184
  headers_str << "#{key}: #{val}#{@nl}"
181
185
  end
182
186
 
183
- return headers_str
187
+ headers_str
184
188
  end
185
189
 
186
190
  def cookie_header_string
187
191
  cstr = ""
188
192
 
189
193
  first = true
190
- @cookies.each do |cookie_name, cookie|
194
+ @cookies.each do |_cookie_name, cookie|
191
195
  cstr << "; " unless first
192
196
  first = false if first
193
197
  ensure_single_lines([cookie.name, cookie.value])
194
198
  cstr << "#{Http2::Utils.urlenc(cookie.name)}=#{Http2::Utils.urlenc(cookie.value)}"
195
199
  end
196
200
 
197
- return cstr
201
+ cstr
198
202
  end
199
203
 
200
204
  def cookie(name)
@@ -216,8 +220,8 @@ class Http2
216
220
  # Reads the response after posting headers and data.
217
221
  #===Examples
218
222
  # res = http.read_response
219
- def read_response(args = {})
220
- ::Http2::ResponseReader.new(http2: self, sock: @sock, args: args).response
223
+ def read_response(request, args = {})
224
+ ::Http2::ResponseReader.new(http2: self, sock: @sock, args: args, request: request).response
221
225
  end
222
226
 
223
227
  def to_s
@@ -231,13 +235,13 @@ class Http2
231
235
  private
232
236
 
233
237
  def host_header
234
- #Possible to give custom host-argument.
238
+ # Possible to give custom host-argument.
235
239
  host = args[:host] || self.host
236
240
  port = args[:port] || self.port
237
241
 
238
242
  host_header_string = "#{host}" # Copy host string to avoid changing the original string if port has been given!
239
243
  host_header_string << ":#{port}" if port && ![80, 443].include?(port.to_i) && !@args[:skip_port_in_host_header]
240
- return host_header_string
244
+ host_header_string
241
245
  end
242
246
 
243
247
  # Registers the states from a result.
@@ -247,7 +251,6 @@ private
247
251
 
248
252
  res.body.to_s.scan(/<input type="hidden" name="__(EVENTTARGET|EVENTARGUMENT|VIEWSTATE|LASTFOCUS)" id="(.*?)" value="(.*?)" \/>/) do |match|
249
253
  name = "__#{match[0]}"
250
- id = match[1]
251
254
  value = match[2]
252
255
 
253
256
  puts "Http2: Registered autostate-value with name '#{name}' and value '#{value}'." if @debug
@@ -266,14 +269,14 @@ private
266
269
  args = {host: args} if args.is_a?(String)
267
270
  raise "Arguments wasnt a hash." unless args.is_a?(Hash)
268
271
 
269
- args.each do |key, val|
272
+ args.each do |key, _val|
270
273
  raise "Invalid key: '#{key}'." unless VALID_ARGUMENTS_INITIALIZE.include?(key)
271
274
  end
272
275
 
273
276
  args[:proxy][:connect] = true if args[:proxy] && !args[:proxy].key?(:connect) && args[:ssl]
274
277
 
275
278
  raise "No host was given." unless args[:host]
276
- return args
279
+ args
277
280
  end
278
281
 
279
282
  def set_default_values
@@ -281,7 +284,7 @@ private
281
284
  @autostate_values = {} if autostate
282
285
  @nl = @args[:nl] || "\r\n"
283
286
 
284
- if !@args[:port]
287
+ unless @args[:port]
285
288
  if @args[:ssl]
286
289
  @args[:port] = 443
287
290
  else
@@ -0,0 +1,22 @@
1
+ class Http2::BaseRequest
2
+ attr_reader :http2, :args, :debug
3
+
4
+ VALID_ARGUMENTS_POST = [:post, :url, :default_headers, :headers, :json, :method, :cookies, :on_content, :content_type]
5
+
6
+ def initialize(http2, args)
7
+ @http2 = http2
8
+ @args = http2.parse_args(args)
9
+ @debug = http2.debug
10
+ @nl = http2.nl
11
+
12
+ @args.each do |key, _val|
13
+ raise "Invalid key: '#{key}'." unless VALID_ARGUMENTS_POST.include?(key)
14
+ end
15
+
16
+ @conn = @http2.connection
17
+ end
18
+
19
+ def path
20
+ @args.fetch(:url)
21
+ end
22
+ end
@@ -1,6 +1,9 @@
1
1
  class Http2::Connection
2
2
  def initialize(http2)
3
- @http2, @debug, @args, @nl = http2, http2.debug, http2.args, http2.nl
3
+ @http2 = http2
4
+ @debug = http2.debug
5
+ @args = http2.args
6
+ @nl = http2.nl
4
7
  reconnect
5
8
  end
6
9
 
@@ -23,10 +26,6 @@ class Http2::Connection
23
26
  @sock.read(length)
24
27
  end
25
28
 
26
- def close
27
- @sock.close
28
- end
29
-
30
29
  def closed?
31
30
  @sock.closed?
32
31
  end
@@ -46,10 +45,12 @@ class Http2::Connection
46
45
  def write(str)
47
46
  reconnect unless socket_working?
48
47
 
48
+ puts "Http2: Writing: #{str}" if @debug
49
+
49
50
  begin
50
51
  raise Errno::EPIPE, "The socket is closed." if !@sock || @sock.closed?
51
52
  sock_write(str)
52
- rescue Errno::EPIPE #this can also be thrown by puts.
53
+ rescue Errno::EPIPE # this can also be thrown by puts.
53
54
  reconnect
54
55
  sock_write(str)
55
56
  end
@@ -61,7 +62,7 @@ class Http2::Connection
61
62
  def reconnect
62
63
  puts "Http2: Reconnect." if @debug
63
64
 
64
- #Open connection.
65
+ # Open connection.
65
66
  if @args[:proxy]
66
67
  if @args[:proxy][:connect]
67
68
  connect_proxy_connect
@@ -84,7 +85,7 @@ class Http2::Connection
84
85
  #===Examples
85
86
  # puts "Socket is working." if http.socket_working?
86
87
  def socket_working?
87
- return false if !@sock or @sock.closed?
88
+ return false if !@sock || @sock.closed?
88
89
 
89
90
  if @keepalive_timeout && @request_last
90
91
  between = Time.now.to_i - @request_last.to_i
@@ -94,7 +95,7 @@ class Http2::Connection
94
95
  end
95
96
  end
96
97
 
97
- return true
98
+ true
98
99
  end
99
100
 
100
101
  # Closes the current connection if any.
@@ -2,7 +2,10 @@ class Http2::Cookie
2
2
  attr_reader :name, :value, :path, :expires_raw
3
3
 
4
4
  def initialize(args)
5
- @name, @value, @path, @expires_raw = args[:name], args[:value], args[:path], args[:expires]
5
+ @name = args[:name]
6
+ @value = args[:value]
7
+ @path = args[:path]
8
+ @expires_raw = args[:expires]
6
9
  end
7
10
 
8
11
  def inspect
@@ -1,4 +1,4 @@
1
- #This class holds various classes for error-handeling.
1
+ # This class holds various classes for error-handeling.
2
2
  class Http2::Errors
3
3
  class Http2error < RuntimeError
4
4
  attr_accessor :response
@@ -0,0 +1,33 @@
1
+ class Http2::GetRequest < Http2::BaseRequest
2
+ def execute
3
+ @http2.mutex.synchronize do
4
+ @http2.connection.write(headers_string)
5
+
6
+ puts "Http2: Reading response." if @debug
7
+ resp = @http2.read_response(self, @args)
8
+
9
+ puts "Http2: Done with get request." if @debug
10
+ return resp
11
+ end
12
+ end
13
+
14
+ def headers_string
15
+ unless @header_str
16
+ @header_str = "#{method} /#{@args[:url]} HTTP/1.1#{@nl}"
17
+ @header_str << @http2.header_str(@http2.default_headers(@args))
18
+ @header_str << @nl
19
+ end
20
+
21
+ @header_str
22
+ end
23
+
24
+ private
25
+
26
+ def method
27
+ if @args[:method]
28
+ @args[:method].to_s.upcase
29
+ else
30
+ "GET"
31
+ end
32
+ end
33
+ end
@@ -1,6 +1,7 @@
1
1
  class Http2::PostDataGenerator
2
2
  def initialize(pdata, args = {})
3
- @pdata, @args = pdata, args
3
+ @pdata = pdata
4
+ @args = args
4
5
  end
5
6
 
6
7
  def generate
@@ -14,7 +15,7 @@ class Http2::PostDataGenerator
14
15
  return @pdata.to_s
15
16
  end
16
17
 
17
- return praw
18
+ praw
18
19
  end
19
20
 
20
21
  private
@@ -22,7 +23,7 @@ private
22
23
  def generate_for_hash(hash)
23
24
  praw = ""
24
25
 
25
- @pdata.each do |key, val|
26
+ hash.each do |key, val|
26
27
  praw << "&" if praw != ""
27
28
  key = "#{@args[:orig_key]}[#{key}]" if @args[:orig_key]
28
29
  praw << generate_key_value(key, val)
@@ -35,7 +36,7 @@ private
35
36
  praw = ""
36
37
 
37
38
  count = 0
38
- @pdata.each do |val|
39
+ array.each do |val|
39
40
  praw << "&" if praw != ""
40
41
 
41
42
  if @args[:orig_key]
@@ -1,42 +1,44 @@
1
1
  require "tempfile"
2
2
 
3
- class Http2::PostMultipartRequest
3
+ class Http2::PostMultipartRequest < Http2::BaseRequest
4
+ attr_reader :headers_string
5
+
4
6
  def initialize(http2, *args)
5
- @http2, @nl, @args = http2, http2.nl, http2.parse_args(*args)
7
+ super
8
+
6
9
  @phash = @args[:post].clone
7
10
  @http2.autostate_set_on_post_hash(phash) if @http2.autostate
8
11
  @boundary = rand(36**50).to_s(36)
9
- @conn = @http2.connection
10
12
  end
11
13
 
12
14
  def execute
13
- generate_raw(@phash) do |helper, praw|
14
- puts "Http2: Header string: #{header_string}" if @debug
15
-
15
+ generate_raw(@phash) do |_helper, praw|
16
16
  @http2.mutex.synchronize do
17
- @conn.write(header_string(praw))
17
+ @conn.write(header_string_with_raw_post(praw))
18
18
 
19
19
  praw.rewind
20
20
  praw.each_line do |data|
21
21
  @conn.sock_write(data)
22
22
  end
23
23
 
24
- return @http2.read_response(@args)
24
+ return @http2.read_response(self, @args)
25
25
  end
26
26
  end
27
27
  end
28
28
 
29
29
  private
30
30
 
31
- def header_string(praw)
32
- header_str = "POST /#{@args[:url]} HTTP/1.1#{@nl}"
33
- header_str << @http2.header_str(@http2.default_headers(@args).merge(
31
+ def header_string_with_raw_post(praw)
32
+ @headers_string = "POST /#{@args[:url]} HTTP/1.1#{@nl}"
33
+
34
+ headers = @http2.default_headers(@args).merge(
34
35
  "Content-Type" => "multipart/form-data; boundary=#{@boundary}",
35
36
  "Content-Length" => praw.size
36
- ), @args)
37
- header_str << @nl
37
+ )
38
38
 
39
- return header_str
39
+ @headers_string << @http2.header_str(headers)
40
+ @headers_string << @nl
41
+ @headers_string
40
42
  end
41
43
 
42
44
  def generate_raw(phash)
@@ -55,10 +57,12 @@ private
55
57
  def read_file(path, praw)
56
58
  File.open(path, "r") do |fp|
57
59
  begin
58
- while data = fp.sysread(4096)
60
+ while (data = fp.sysread(4096))
59
61
  praw << data
60
62
  end
63
+ # rubocop:disable Lint/HandleExceptions
61
64
  rescue EOFError
65
+ # rubocop:enable Lint/HandleExceptions
62
66
  # Happens when done.
63
67
  end
64
68
  end