http2 0.0.28 → 0.0.33
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +150 -28
- data/Rakefile +20 -31
- data/lib/http2.rb +105 -70
- data/lib/http2/base_request.rb +22 -0
- data/{include → lib/http2}/connection.rb +56 -28
- data/lib/http2/cookie.rb +22 -0
- data/lib/http2/errors.rb +18 -0
- data/lib/http2/get_request.rb +33 -0
- data/{include → lib/http2}/post_data_generator.rb +7 -6
- data/{include → lib/http2}/post_multipart_request.rb +20 -20
- data/{include → lib/http2}/post_request.rb +17 -22
- data/lib/http2/response.rb +109 -0
- data/{include → lib/http2}/response_reader.rb +75 -42
- data/{include → lib/http2}/url_builder.rb +6 -6
- data/lib/http2/utils.rb +52 -0
- data/spec/helpers.rb +27 -0
- data/spec/http2/cookies_spec.rb +18 -0
- data/spec/http2/get_request_spec.rb +11 -0
- data/spec/http2/post_data_generator_spec.rb +2 -1
- data/spec/http2/post_multipart_request_spec.rb +11 -0
- data/spec/http2/post_request_spec.rb +11 -0
- data/spec/http2/response_reader_spec.rb +12 -0
- data/spec/http2/response_spec.rb +73 -0
- data/spec/http2/url_builder_spec.rb +1 -1
- data/spec/http2_spec.rb +107 -89
- data/spec/spec_helper.rb +8 -8
- data/spec/spec_root/content_type_test.rhtml +4 -0
- data/spec/spec_root/cookie_test.rhtml +8 -0
- data/spec/spec_root/json_test.rhtml +9 -0
- data/spec/spec_root/multipart_test.rhtml +28 -0
- data/spec/spec_root/redirect_test.rhtml +3 -0
- data/spec/spec_root/unauthorized.rhtml +3 -0
- data/spec/spec_root/unsupported_media_type.rhtml +3 -0
- metadata +118 -36
- data/.document +0 -5
- data/.rspec +0 -1
- data/Gemfile +0 -14
- data/Gemfile.lock +0 -77
- data/VERSION +0 -1
- data/http2.gemspec +0 -77
- data/include/errors.rb +0 -11
- data/include/get_request.rb +0 -34
- data/include/response.rb +0 -73
- data/include/utils.rb +0 -40
- data/shippable.yml +0 -7
data/spec/helpers.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
module Helpers
|
2
|
+
def with_webserver
|
3
|
+
require "hayabusa"
|
4
|
+
hayabusa = Hayabusa.new(
|
5
|
+
doc_root: "#{File.dirname(__FILE__)}/spec_root",
|
6
|
+
port: 3005
|
7
|
+
)
|
8
|
+
hayabusa.start
|
9
|
+
|
10
|
+
begin
|
11
|
+
yield(hayabusa)
|
12
|
+
ensure
|
13
|
+
hayabusa.stop
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def with_http(args = {})
|
18
|
+
with_webserver do |hayabusa|
|
19
|
+
Http2.new({host: "localhost", port: hayabusa.port, encoding_gzip: false}.merge(args)) do |http|
|
20
|
+
yield http
|
21
|
+
end
|
22
|
+
rescue Http2::Errors::Internalserver => e
|
23
|
+
puts "Body of error-response: #{e.response.body}"
|
24
|
+
raise e
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Http2 do
|
4
|
+
include Helpers
|
5
|
+
|
6
|
+
it "should parse cookies and let them be read" do
|
7
|
+
with_http do |http|
|
8
|
+
http.get("cookie_test.rhtml")
|
9
|
+
expect(http.cookies.length).to eq 2
|
10
|
+
|
11
|
+
cookie = http.cookie("TestCookie")
|
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
|
+
end
|
17
|
+
end
|
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
|
@@ -19,6 +19,7 @@ describe Http2::PostDataGenerator do
|
|
19
19
|
}
|
20
20
|
}
|
21
21
|
).generate
|
22
|
-
|
22
|
+
|
23
|
+
expect(res).to eq "test1%5Border%5D%5B%5B%3ABnet_profile%2C+%22profile_id%22%5D%5D=5"
|
23
24
|
end
|
24
25
|
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
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Http2::Response do
|
4
|
+
it "#content_type" do
|
5
|
+
with_http do |http|
|
6
|
+
res = http.get("content_type_test.rhtml")
|
7
|
+
expect(res.content_type).to eq "text/html"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
it "#content_length" do
|
12
|
+
with_http do |http|
|
13
|
+
res = http.get("content_type_test.rhtml")
|
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")
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -11,7 +11,7 @@ describe Http2::UrlBuilder do
|
|
11
11
|
ub.params["test"] = "true"
|
12
12
|
ub.params["test2"] = "false"
|
13
13
|
|
14
|
-
ub.build.
|
14
|
+
expect(ub.build).to eq "https://www.github.com:443/index.php?test=true&test2=false"
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
data/spec/http2_spec.rb
CHANGED
@@ -1,157 +1,175 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
|
+
require "json"
|
2
3
|
|
3
4
|
describe "Http2" do
|
4
5
|
it "should be able to do normal post-requests." do
|
5
|
-
|
6
|
-
|
7
|
-
#Test posting keep-alive and advanced post-data.
|
8
|
-
Http2.new(host: "www.partyworm.dk", debug: false) do |http|
|
6
|
+
# Test posting keep-alive and advanced post-data.
|
7
|
+
with_http do |http|
|
9
8
|
0.upto(5) do
|
10
|
-
|
11
|
-
|
12
|
-
resp = http.post(
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
"
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
9
|
+
http.get("multipart_test.rhtml")
|
10
|
+
|
11
|
+
resp = http.post(
|
12
|
+
url: "multipart_test.rhtml?choice=post-test",
|
13
|
+
post: {
|
14
|
+
"val1" => "test1",
|
15
|
+
"val2" => "test2",
|
16
|
+
"val3" => [
|
17
|
+
"test3"
|
18
|
+
],
|
19
|
+
"val4" => {
|
20
|
+
"val5" => "test5"
|
21
|
+
},
|
22
|
+
"val6" => {
|
23
|
+
"val7" => [
|
24
|
+
{
|
25
|
+
"val8" => "test8"
|
26
|
+
}
|
27
|
+
]
|
28
|
+
},
|
29
|
+
"val9" => %w[a b d]
|
30
|
+
}
|
31
|
+
)
|
30
32
|
res = JSON.parse(resp.body)
|
31
33
|
|
32
|
-
res.is_a?(Hash).
|
33
|
-
res["val1"].
|
34
|
-
res["val2"].
|
35
|
-
res["val3"][0].
|
36
|
-
res["val4"]["val5"].
|
37
|
-
res["val6"]["val7"][0]["val8"].
|
38
|
-
res["val9"][0].
|
39
|
-
res["val9"][1].
|
40
|
-
res["val9"][2].
|
34
|
+
expect(res.is_a?(Hash)).to eq true
|
35
|
+
expect(res["val1"]).to eq "test1"
|
36
|
+
expect(res["val2"]).to eq "test2"
|
37
|
+
expect(res["val3"]["0"]).to eq "test3"
|
38
|
+
expect(res["val4"]["val5"]).to eq "test5"
|
39
|
+
expect(res["val6"]["val7"]["0"]["val8"]).to eq "test8"
|
40
|
+
expect(res["val9"]["0"]).to eq "a"
|
41
|
+
expect(res["val9"]["1"]).to eq "b"
|
42
|
+
expect(res["val9"]["2"]).to eq "d"
|
41
43
|
end
|
42
44
|
end
|
43
45
|
end
|
44
46
|
|
45
47
|
it "#reconnect" do
|
46
|
-
|
47
|
-
resp1 = http.get("multipart_test.
|
48
|
+
with_http(follow_redirects: false, encoding_gzip: false) do |http|
|
49
|
+
resp1 = http.get("multipart_test.rhtml")
|
48
50
|
http.reconnect
|
49
|
-
resp2 = http.get("multipart_test.
|
51
|
+
resp2 = http.get("multipart_test.rhtml")
|
50
52
|
|
51
|
-
resp1.body.
|
53
|
+
expect(resp1.body).to eq resp2.body
|
52
54
|
end
|
53
55
|
end
|
54
56
|
|
55
57
|
it "should be able to do multipart-requests and keep-alive when using multipart." do
|
56
|
-
|
58
|
+
with_http(follow_redirects: false) do |http|
|
57
59
|
0.upto(5) do
|
58
60
|
fpath = File.realpath(__FILE__)
|
59
61
|
fpath2 = "#{File.realpath(File.dirname(__FILE__))}/../lib/http2.rb"
|
60
62
|
|
61
|
-
resp = http.post_multipart(
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
63
|
+
resp = http.post_multipart(
|
64
|
+
url: "multipart_test.rhtml",
|
65
|
+
post: {
|
66
|
+
"test_var" => "true",
|
67
|
+
"test_file1" => {
|
68
|
+
fpath: fpath,
|
69
|
+
filename: "specfile"
|
70
|
+
},
|
71
|
+
"test_file2" => {
|
72
|
+
fpath: fpath2,
|
73
|
+
filename: "http2.rb"
|
74
|
+
}
|
70
75
|
}
|
71
|
-
|
76
|
+
)
|
72
77
|
|
73
78
|
data = JSON.parse(resp.body)
|
74
79
|
|
75
|
-
data["post"]["test_var"].
|
76
|
-
data["files_data"]["test_file1"].
|
77
|
-
data["files_data"]["test_file2"].
|
80
|
+
expect(data["post"]["test_var"]).to eq "true"
|
81
|
+
expect(data["files_data"]["test_file1"]).to eq File.read(fpath)
|
82
|
+
expect(data["files_data"]["test_file2"]).to eq File.read(fpath2)
|
78
83
|
end
|
79
84
|
end
|
80
85
|
end
|
81
86
|
|
82
87
|
it "it should be able to handle keep-alive correctly" do
|
83
88
|
urls = [
|
84
|
-
"
|
85
|
-
"
|
86
|
-
"?show=drinksdb",
|
87
|
-
"?show=forum&fid=9&tid=1917&page=0"
|
89
|
+
"content_type_test.rhtml",
|
90
|
+
"json_test.rhtml"
|
88
91
|
]
|
89
|
-
urls = ["robots.txt"]
|
90
92
|
|
91
|
-
|
92
|
-
0.upto(105) do |
|
93
|
+
with_http do |http|
|
94
|
+
0.upto(105) do |_count|
|
93
95
|
url = urls[rand(urls.size)]
|
94
|
-
#
|
96
|
+
# puts "Doing request #{count} of 200 (#{url})."
|
95
97
|
res = http.get(url)
|
96
|
-
res.body.to_s.length.
|
98
|
+
expect(res.body.to_s.length).to be > 0
|
97
99
|
end
|
98
100
|
end
|
99
101
|
end
|
100
102
|
|
101
|
-
it "should be able to convert URL's to 'is.gd'-short-urls" do
|
102
|
-
isgd = Http2.isgdlink("https://github.com/kaspernj/http2")
|
103
|
-
raise "Expected isgd-var to be valid but it wasnt: '#{isgd}'." if !isgd.match(/^http:\/\/is\.gd\/([A-z\d]+)$/)
|
104
|
-
end
|
105
|
-
|
106
103
|
it "should raise exception when something is not found" do
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
end
|
111
|
-
}.to raise_error(::Http2::Errors::Notfound)
|
104
|
+
with_http do |http|
|
105
|
+
expect { http.get("something_that_does_not_exist.rhtml") }.to raise_error(::Http2::Errors::Notfound)
|
106
|
+
end
|
112
107
|
end
|
113
108
|
|
114
109
|
it "should be able to post json" do
|
115
|
-
|
110
|
+
with_http do |http|
|
116
111
|
res = http.post(
|
117
|
-
url: "
|
112
|
+
url: "json_test.rhtml",
|
118
113
|
json: {testkey: "testvalue"}
|
119
114
|
)
|
120
115
|
|
121
116
|
data = JSON.parse(res.body)
|
122
|
-
data["_SERVER"]["
|
123
|
-
|
117
|
+
expect(data["_SERVER"]["HTTP_CONTENT_TYPE"]).to eq "application/json"
|
118
|
+
|
119
|
+
# Hack JSON data from Hayabusa.
|
120
|
+
json_data = JSON.parse(data["_POST"].keys.first)
|
121
|
+
expect(json_data["testkey"]).to eq "testvalue"
|
122
|
+
|
123
|
+
expect(res.content_type).to eq "application/json"
|
124
|
+
expect(res.json?).to eq true
|
125
|
+
expect(res.json["_SERVER"]["REQUEST_METHOD"]).to eq "POST"
|
124
126
|
end
|
125
127
|
end
|
126
128
|
|
127
129
|
it "should be able to post custom content types" do
|
128
|
-
|
129
|
-
|
130
|
-
Http2.new(host: "http2test.kaspernj.org") do |http|
|
130
|
+
with_http do |http|
|
131
131
|
res = http.post(
|
132
|
-
url: "content_type_test.
|
132
|
+
url: "content_type_test.rhtml",
|
133
133
|
content_type: "plain/text",
|
134
134
|
post: "test1_test2_test3"
|
135
135
|
)
|
136
136
|
|
137
137
|
data = JSON.parse(res.body)
|
138
|
-
data["_SERVER"]["
|
139
|
-
|
138
|
+
expect(data["_SERVER"]["HTTP_CONTENT_TYPE"]).to eq "plain/text"
|
139
|
+
|
140
|
+
raw_data = data["_POST"].keys.first
|
141
|
+
expect(raw_data).to eq "test1_test2_test3"
|
140
142
|
end
|
141
143
|
end
|
142
144
|
|
143
145
|
it "should set various timeouts" do
|
144
|
-
|
145
|
-
|
146
|
-
http.keepalive_timeout.
|
147
|
-
http.keepalive_max.
|
146
|
+
with_http do |http|
|
147
|
+
http.get("content_type_test.rhtml")
|
148
|
+
expect(http.keepalive_timeout).to eq 15
|
149
|
+
expect(http.keepalive_max).to eq 30
|
148
150
|
end
|
149
151
|
end
|
150
152
|
|
151
153
|
it "should follow redirects" do
|
152
|
-
|
153
|
-
resp = http.get("redirect_test.
|
154
|
-
resp.code.
|
154
|
+
with_http(follow_redirects: true) do |http|
|
155
|
+
resp = http.get("redirect_test.rhtml")
|
156
|
+
expect(resp.code).to eq "200"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
it "throws errors on unauhtorized" do
|
161
|
+
with_http do |http|
|
162
|
+
expect do
|
163
|
+
http.get("unauthorized.rhtml")
|
164
|
+
end.to raise_error(Http2::Errors::Unauthorized)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
it "throws errors on unsupported media type" do
|
169
|
+
with_http do |http|
|
170
|
+
expect do
|
171
|
+
http.get("unsupported_media_type.rhtml")
|
172
|
+
end.to raise_error(Http2::Errors::UnsupportedMediaType)
|
155
173
|
end
|
156
174
|
end
|
157
|
-
end
|
175
|
+
end
|