http2 0.0.31 → 0.0.32

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,13 +1,13 @@
1
- class Http2::PostRequest
2
- VALID_ARGUMENTS_POST = [:post, :url, :default_headers, :headers, :json, :method, :cookies, :on_content, :content_type]
3
-
4
- def initialize(http2, args)
5
- args.each do |key, val|
6
- raise "Invalid key: '#{key}'." unless VALID_ARGUMENTS_POST.include?(key)
1
+ class Http2::PostRequest < Http2::BaseRequest
2
+ def headers_string
3
+ unless @headers_string
4
+ @headers_string = "#{method} /#{@args[:url]} HTTP/1.1#{@nl}"
5
+ @headers_string << @http2.header_str(headers)
6
+ @headers_string << @nl
7
+ @headers_string << @data
7
8
  end
8
9
 
9
- @http2, @args, @debug, @nl = http2, http2.parse_args(args), http2.debug, http2.nl
10
- @conn = @http2.connection
10
+ @headers_string
11
11
  end
12
12
 
13
13
  def execute
@@ -15,10 +15,9 @@ class Http2::PostRequest
15
15
 
16
16
  @http2.mutex.synchronize do
17
17
  puts "Http2: Doing post." if @debug
18
- puts "Http2: Header str: #{header_string}" if @debug
19
18
 
20
- @conn.write(header_string)
21
- return @http2.read_response(@args)
19
+ @conn.write(headers_string)
20
+ return @http2.read_response(self, @args)
22
21
  end
23
22
  end
24
23
 
@@ -36,7 +35,7 @@ private
36
35
  if @args[:content_type]
37
36
  @args[:content_type]
38
37
  elsif @args[:json]
39
- content_type = "application/json"
38
+ "application/json"
40
39
  else
41
40
  "application/x-www-form-urlencoded"
42
41
  end
@@ -63,20 +62,9 @@ private
63
62
  headers_hash.merge! @http2.default_headers(@args)
64
63
 
65
64
  unless headers_hash["Accept"]
66
- if @args[:json]
67
- headers_hash["Accept"] = "application/json"
68
- end
65
+ headers_hash["Accept"] = "application/json" if @args[:json]
69
66
  end
70
67
 
71
- return headers_hash
72
- end
73
-
74
- def header_string
75
- header_str = "#{method} /#{@args[:url]} HTTP/1.1#{@nl}"
76
- header_str << @http2.header_str(headers, @args)
77
- header_str << @nl
78
- header_str << @data
79
-
80
- header_str
68
+ headers_hash
81
69
  end
82
70
  end
@@ -1,38 +1,39 @@
1
- #This object will be returned as the response for each request.
1
+ # This object will be returned as the response for each request.
2
2
  class Http2::Response
3
- #All the data the response contains. Headers, body, cookies, requested URL and more.
4
- attr_reader :args
3
+ # All the data the response contains. Headers, body, cookies, requested URL and more.
4
+ attr_reader :args, :request
5
5
  attr_accessor :body, :charset, :code, :content_type, :http_version
6
6
 
7
- #This method should not be called manually.
7
+ # This method should not be called manually.
8
8
  def initialize(args = {})
9
9
  @args = args
10
- @args[:headers] = {} unless @args.key?(:headers)
10
+ @args[:headers] ||= {}
11
11
  @body = args[:body] || ""
12
- @debug = @args[:debug]
12
+ @debug = args[:debug]
13
+ @request = args.fetch(:request)
13
14
  end
14
15
 
15
- #Returns headers given from the host for the result.
16
+ # Returns headers given from the host for the result.
16
17
  #===Examples
17
18
  # headers_hash = res.headers
18
19
  def headers
19
- return @args[:headers]
20
+ @args.fetch(:headers)
20
21
  end
21
22
 
22
- #Returns a certain header by name or false if not found.
23
+ # Returns a certain header by name or false if not found.
23
24
  #===Examples
24
25
  # val = res.header("content-type")
25
26
  def header(key)
26
- return false if !@args[:headers].key?(key)
27
- return @args[:headers][key].first.to_s
27
+ return false unless @args.fetch(:headers).key?(key)
28
+ @args.fetch(:headers).fetch(key).first.to_s
28
29
  end
29
30
 
30
- #Returns true if a header of the given string exists.
31
+ # Returns true if a header of the given string exists.
31
32
  #===Examples
32
33
  # print "No content-type was given." if !http.header?("content-type")
33
34
  def header?(key)
34
35
  return true if @args[:headers].key?(key) && @args[:headers][key].first.to_s.length > 0
35
- return false
36
+ false
36
37
  end
37
38
 
38
39
  def content_length
@@ -53,12 +54,12 @@ class Http2::Response
53
54
  end
54
55
  end
55
56
 
56
- #Returns the requested URL as a string.
57
+ # Returns the requested URL as a string.
57
58
  #===Examples
58
59
  # res.requested_url #=> "?show=status&action=getstatus"
59
60
  def requested_url
60
61
  raise "URL could not be detected." unless @args[:request_args][:url]
61
- return @args[:request_args][:url]
62
+ @args[:request_args][:url]
62
63
  end
63
64
 
64
65
  # Checks the data that has been sat on the object and raises various exceptions, if it does not validate somehow.
@@ -76,6 +77,30 @@ class Http2::Response
76
77
  @json ||= JSON.parse(body)
77
78
  end
78
79
 
80
+ def host
81
+ @request.http2.host
82
+ end
83
+
84
+ def port
85
+ @request.http2.port
86
+ end
87
+
88
+ def ssl?
89
+ @request.http2.ssl?
90
+ end
91
+
92
+ def path
93
+ @request.path
94
+ end
95
+
96
+ def to_s
97
+ "#<Http::Response host=\"#{host}\" port=#{port} ssl=#{ssl?} path=\"#{path}\">"
98
+ end
99
+
100
+ def inspect
101
+ to_s
102
+ end
103
+
79
104
  private
80
105
 
81
106
  # Checks that the length of the body is the same as the given content-length if given.
@@ -4,9 +4,12 @@ class Http2::ResponseReader
4
4
  def initialize(args)
5
5
  @mode = "headers"
6
6
  @transfer_encoding = nil
7
- @response = Http2::Response.new(request_args: args, debug: @debug)
7
+ @response = Http2::Response.new(request: args.fetch(:request), request_args: args, debug: @debug)
8
8
  @rec_count = 0
9
- @args, @debug, @http2, @sock = args[:args], args[:http2].debug, args[:http2], args[:sock]
9
+ @args = args[:args]
10
+ @debug = args[:http2].debug
11
+ @http2 = args[:http2]
12
+ @sock = args[:sock]
10
13
  @nl = @http2.nl
11
14
  @conn = @http2.connection
12
15
 
@@ -49,7 +52,7 @@ class Http2::ResponseReader
49
52
  end
50
53
 
51
54
  def finish
52
- #Check if we should reconnect based on keep-alive-max.
55
+ # Check if we should reconnect based on keep-alive-max.
53
56
  if @keepalive_max == 1 || @connection == "close"
54
57
  @conn.close unless @conn.closed?
55
58
  end
@@ -66,7 +69,7 @@ class Http2::ResponseReader
66
69
  @http2.autostate_register(@response) if @http2.args[:autostate]
67
70
  handle_errors
68
71
 
69
- if response = check_and_follow_redirect
72
+ if (response = check_and_follow_redirect)
70
73
  @response = response
71
74
  end
72
75
  end
@@ -100,14 +103,19 @@ private
100
103
 
101
104
  def url_and_args_from_location
102
105
  uri = URI.parse(@response.header("location"))
106
+
103
107
  url = uri.path
104
108
  url << "?#{uri.query}" if uri.query.to_s.length > 0
109
+ url = url.gsub(/\A\//, "")
110
+
111
+ args = @http2.args
112
+ .reject { |k, _v| [:ssl, :port].include? k }
113
+ .merge(host: uri.host)
105
114
 
106
- args = {host: uri.host}
107
115
  args[:ssl] = true if uri.scheme == "https"
108
116
  args[:port] = uri.port if uri.port
109
117
 
110
- return [url, args]
118
+ [url, args]
111
119
  end
112
120
 
113
121
  def check_and_decode
@@ -123,7 +131,7 @@ private
123
131
  begin
124
132
  valid_string = ic.encode("UTF-8")
125
133
  rescue
126
- valid_string = untrusted_str.force_encoding("UTF-8").encode("UTF-8", :invalid => :replace, :replace => "").encode("UTF-8")
134
+ valid_string = untrusted_str.force_encoding("UTF-8").encode("UTF-8", invalid: :replace, replace: "").encode("UTF-8")
127
135
  end
128
136
 
129
137
  @response.body = valid_string
@@ -131,7 +139,7 @@ private
131
139
  end
132
140
 
133
141
  def handle_errors
134
- return unless @http2.raise_errors
142
+ return unless @http2.raise_errors
135
143
 
136
144
  if @response.code == "500"
137
145
  err = Http2::Errors::Internalserver.new("A internal server error occurred")
@@ -176,7 +184,7 @@ private
176
184
  end
177
185
 
178
186
  def parse_content_type(content_type_line)
179
- if match_charset = content_type_line.match(/\s*;\s*charset=(.+)/i)
187
+ if (match_charset = content_type_line.match(/\s*;\s*charset=(.+)/i))
180
188
  @charset = match_charset[1].downcase
181
189
  @response.charset = @charset
182
190
  content_type_line.gsub!(match_charset[0], "")
@@ -185,15 +193,15 @@ private
185
193
  @response.content_type = content_type_line
186
194
  end
187
195
 
188
- #Parse a header-line and saves it on the object.
196
+ # Parse a header-line and saves it on the object.
189
197
  #===Examples
190
198
  # http.parse_header("Content-Type: text/html\r\n")
191
199
  def parse_header(line)
192
- if match = line.match(/^(.+?):\s*(.+)#{@nl}$/)
200
+ if (match = line.match(/^(.+?):\s*(.+)#{@nl}$/))
193
201
  key = match[1].downcase
194
202
  set_header_special_values(key, match[2])
195
203
  parse_normal_header(line, key, match[1], match[2])
196
- elsif match = line.match(/^HTTP\/([\d\.]+)\s+(\d+)\s+(.+)$/)
204
+ elsif (match = line.match(/^HTTP\/([\d\.]+)\s+(\d+)\s+(.+)$/))
197
205
  @response.code = match[2]
198
206
  @response.http_version = match[1]
199
207
  @http2.on_content_call(@args, line)
@@ -229,7 +237,7 @@ private
229
237
  end
230
238
  end
231
239
 
232
- #Parses the body based on given headers and saves it to the result-object.
240
+ # Parses the body based on given headers and saves it to the result-object.
233
241
  # http.parse_body(str)
234
242
  def parse_body(line)
235
243
  return :break if @length == 0
@@ -1,7 +1,7 @@
1
1
  class Http2::UrlBuilder
2
2
  attr_accessor :host, :port, :protocol, :path, :params
3
3
 
4
- def initialize args = {}
4
+ def initialize
5
5
  @params = {}
6
6
  end
7
7
 
@@ -24,7 +24,7 @@ class Http2::UrlBuilder
24
24
  end
25
25
  end
26
26
 
27
- return url_params
27
+ url_params
28
28
  end
29
29
 
30
30
  def build_path_and_params
@@ -35,7 +35,7 @@ class Http2::UrlBuilder
35
35
  url << build_params
36
36
  end
37
37
 
38
- return url
38
+ url
39
39
  end
40
40
 
41
41
  def build
@@ -49,7 +49,7 @@ class Http2::UrlBuilder
49
49
 
50
50
  url << build_path_and_params
51
51
 
52
- return url
52
+ url
53
53
  end
54
54
 
55
55
  def params?
@@ -2,17 +2,17 @@
2
2
  class Http2::Utils
3
3
  # URL-encodes a string.
4
4
  def self.urlenc(string)
5
- #Thanks to CGI framework
5
+ # Thanks to CGI framework
6
6
  string.to_s.gsub(/([^ a-zA-Z0-9_.-]+)/) do
7
- '%' + $1.unpack('H2' * $1.bytesize).join('%').upcase
8
- end.tr(' ', '+')
7
+ "%" + $1.unpack("H2" * $1.bytesize).join("%").upcase
8
+ end.tr(" ", "+")
9
9
  end
10
10
 
11
11
  # URL-decodes a string.
12
12
  def self.urldec(string)
13
- #Thanks to CGI framework
14
- str = string.to_s.tr('+', ' ').gsub(/((?:%[0-9a-fA-F]{2})+)/) do
15
- [$1.delete('%')].pack('H*')
13
+ # Thanks to CGI framework
14
+ string.to_s.tr("+", " ").gsub(/((?:%[0-9a-fA-F]{2})+)/) do
15
+ [$1.delete("%")].pack("H*")
16
16
  end
17
17
  end
18
18
 
@@ -28,10 +28,10 @@ class Http2::Utils
28
28
 
29
29
  cookie_data = {
30
30
  name: urldec(match[1].to_s),
31
- value: self.urldec(match[2].to_s)
31
+ value: urldec(match[2].to_s)
32
32
  }
33
33
 
34
- while match = str.match(/(.+?)=(.*?)(;\s*|$)/)
34
+ while (match = str.match(/(.+?)=(.*?)(;\s*|$)/))
35
35
  str = str.gsub(match[0], "")
36
36
  key = match[1].to_s.downcase
37
37
  value = match[2].to_s
@@ -45,6 +45,6 @@ class Http2::Utils
45
45
 
46
46
  cookie = Http2::Cookie.new(cookie_data)
47
47
 
48
- return [cookie]
48
+ [cookie]
49
49
  end
50
50
  end
@@ -5,14 +5,14 @@ describe Http2 do
5
5
 
6
6
  it "should parse cookies and let them be read" do
7
7
  with_http do |http|
8
- res = http.get("cookie_test.rhtml")
9
- http.cookies.length.should eq 2
8
+ http.get("cookie_test.rhtml")
9
+ expect(http.cookies.length).to eq 2
10
10
 
11
11
  cookie = http.cookie("TestCookie")
12
- cookie.name.should eq "TestCookie"
13
- cookie.value.should eq "TestValue"
14
- cookie.path.should eq "/"
15
- cookie.expires.should > Time.now
12
+ expect(cookie.name).to eq "TestCookie"
13
+ expect(cookie.value).to eq "TestValue"
14
+ expect(cookie.path).to eq "/"
15
+ expect(cookie.expires).to be > Time.now
16
16
  end
17
17
  end
18
18
  end
@@ -0,0 +1,11 @@
1
+ require "spec_helper"
2
+
3
+ describe Http2::GetRequest do
4
+ it "reads the headers from the request" do
5
+ with_http do |http|
6
+ res = http.get("content_type_test.rhtml")
7
+ headers = res.request.headers_string
8
+ expect(headers).to include "GET /content_type_test.rhtml"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ require "spec_helper"
2
+
3
+ describe Http2::PostMultipartRequest do
4
+ it "reads the headers from the request" do
5
+ with_http do |http|
6
+ res = http.post_multipart(url: "json_test.rhtml", post: {"test1" => "test2"})
7
+ headers = res.request.headers_string
8
+ expect(headers).to include "POST /json_test.rhtml"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ require "spec_helper"
2
+
3
+ describe Http2::PostRequest do
4
+ it "reads the headers from the request" do
5
+ with_http do |http|
6
+ res = http.post(url: "json_test.rhtml", json: {testkey: "testvalue"})
7
+ headers = res.request.headers_string
8
+ expect(headers).to include "POST /json_test.rhtml"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ require "spec_helper"
2
+
3
+ describe Http2::ResponseReader do
4
+ it "#url_and_args_from_location" do
5
+ with_http(ssl_skip_verify: true, follow_redirects: true) do |http|
6
+ response = http.get("redirect_test.rhtml?redirect_to=https://www.google.dk")
7
+ expect(response.host).to eq "www.google.dk"
8
+ expect(response.ssl?).to eq true
9
+ expect(response.port).to eq 443
10
+ end
11
+ end
12
+ end
@@ -1,17 +1,73 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe Http2::Response do
4
- it "should register content type" do
4
+ it "#content_type" do
5
5
  with_http do |http|
6
6
  res = http.get("content_type_test.rhtml")
7
- res.content_type.should eq "text/html"
7
+ expect(res.content_type).to eq "text/html"
8
8
  end
9
9
  end
10
10
 
11
- it "should register content length" do
11
+ it "#content_length" do
12
12
  with_http do |http|
13
13
  res = http.get("content_type_test.rhtml")
14
- res.content_length.should > 50
14
+ expect(res.content_length).to be > 50
15
+ end
16
+ end
17
+
18
+ it "#json?" do
19
+ with_http do |http|
20
+ res = http.get("json_test.rhtml")
21
+ expect(res.json?).to eq true
22
+ end
23
+ end
24
+
25
+ it "#host" do
26
+ with_http do |http|
27
+ res = http.get("json_test.rhtml")
28
+ expect(res.host).to eq "localhost"
29
+ end
30
+ end
31
+
32
+ it "#port" do
33
+ with_http do |http|
34
+ res = http.get("json_test.rhtml")
35
+ expect(res.port).to eq http.port
36
+ end
37
+ end
38
+
39
+ it "#ssl?" do
40
+ with_http do |http|
41
+ res = http.get("json_test.rhtml")
42
+ expect(res.ssl?).to eq false
43
+ end
44
+ end
45
+
46
+ it "#path" do
47
+ with_http do |http|
48
+ res = http.get("json_test.rhtml")
49
+ expect(res.path).to eq "json_test.rhtml"
50
+ end
51
+ end
52
+
53
+ it "#header" do
54
+ with_http do |http|
55
+ res = http.get("json_test.rhtml")
56
+ expect(res.header("connection")).to eq "Keep-Alive"
57
+ end
58
+ end
59
+
60
+ it "#header?" do
61
+ with_http do |http|
62
+ res = http.get("json_test.rhtml")
63
+ expect(res.header?("connection")).to eq true
64
+ end
65
+ end
66
+
67
+ it "#json" do
68
+ with_http do |http|
69
+ res = http.post(url: "json_test.rhtml", post: {test: "test2"})
70
+ expect(res.json["_POST"]).to eq("test" => "test2")
15
71
  end
16
72
  end
17
73
  end