http2 0.0.30 → 0.0.31
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +37 -2
- data/include/connection.rb +36 -19
- data/include/cookie.rb +19 -0
- data/include/response_reader.rb +19 -6
- data/include/utils.rb +22 -12
- data/lib/http2.rb +52 -40
- data/spec/http2/cookies_spec.rb +18 -0
- data/spec/spec_root/cookie_test.rhtml +8 -0
- metadata +18 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 00dd7c4f177f2a7c84ef8f9ef463fe6f2675a400
|
4
|
+
data.tar.gz: 7c28395bf02c20a50d2b8633e6ddd8156c8972f3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bdc915bf5453cb50d0d58e298f661b833d5086f370d66bfda2e5f654d01572ea4880f340d99dd3e6853abfd20e6d3a7bed5892758add2ad4c7187087f71e59b4
|
7
|
+
data.tar.gz: 54923d3a26cfe73698df0fbde92cd1dd517b61efaad45e77102fb469716d3efc4833b337bb2d915fb367d826e6370b5e068e6175a8ea7884b6b14bc9069f3024
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
[![Build Status](https://api.shippable.com/projects/
|
1
|
+
[![Build Status](https://api.shippable.com/projects/540e7b9b3479c5ea8f9ec21d/badge?branchName=master)](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
|
|
@@ -23,7 +23,17 @@ http = Http2.new(...)
|
|
23
23
|
|
24
24
|
# Do requests here.
|
25
25
|
|
26
|
-
http.
|
26
|
+
http.destroy # Closes the connection and frees up any variables used
|
27
|
+
```
|
28
|
+
|
29
|
+
Or through a proxy:
|
30
|
+
```ruby
|
31
|
+
Http2.new(host: "www.google.com", proxy: {host: "myproxy.com", port: 80, user: "myname", passwd: "mypassword"})
|
32
|
+
```
|
33
|
+
|
34
|
+
You can also use SSL:
|
35
|
+
```ruby
|
36
|
+
Http2.new(host: "myhost.com", ssl: true, ssl_skip_verify: true)
|
27
37
|
```
|
28
38
|
|
29
39
|
## Get requests
|
@@ -31,6 +41,11 @@ http.close
|
|
31
41
|
res = http.get("path/to/something")
|
32
42
|
```
|
33
43
|
|
44
|
+
Or as a hash:
|
45
|
+
```ruby
|
46
|
+
res = http.get(url: "path/to/something")
|
47
|
+
```
|
48
|
+
|
34
49
|
## Post requests
|
35
50
|
```ruby
|
36
51
|
res = http.post(url: "path/to/something", post: {
|
@@ -52,6 +67,13 @@ res = http.post(
|
|
52
67
|
res = http.post(url: "path/to/something", json: {some_argument: true})
|
53
68
|
```
|
54
69
|
|
70
|
+
### Reading JSON from request
|
71
|
+
```ruby
|
72
|
+
res = http.post(url: "something", json: {some_argument: true})
|
73
|
+
res.json? #=> true (if content-type is application/json)
|
74
|
+
res.json #=> {"value" => "something"}
|
75
|
+
```
|
76
|
+
|
55
77
|
## Delete requests
|
56
78
|
```ruby
|
57
79
|
res = http.delete(url: "path/to/something")
|
@@ -120,6 +142,19 @@ Handy when doing retries.
|
|
120
142
|
http.reconnect
|
121
143
|
```
|
122
144
|
|
145
|
+
|
146
|
+
## Basic HTTP authentication for all requests
|
147
|
+
|
148
|
+
```ruby
|
149
|
+
http = Http2.new(
|
150
|
+
host: "www.somehost.com",
|
151
|
+
basic_auth: {
|
152
|
+
user: "username",
|
153
|
+
passwd: "password"
|
154
|
+
}
|
155
|
+
)
|
156
|
+
```
|
157
|
+
|
123
158
|
## Contributing to http2
|
124
159
|
|
125
160
|
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
data/include/connection.rb
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
class Http2::Connection
|
2
2
|
def initialize(http2)
|
3
|
-
@http2, @debug, @args = http2, http2.debug, http2.args
|
3
|
+
@http2, @debug, @args, @nl = http2, http2.debug, http2.args, http2.nl
|
4
4
|
reconnect
|
5
5
|
end
|
6
6
|
|
7
7
|
def destroy
|
8
|
-
@sock.close if @sock
|
8
|
+
@sock.close if @sock && !@sock.closed?
|
9
9
|
@sock = nil
|
10
10
|
|
11
|
-
@sock_plain.close if @sock_plain
|
11
|
+
@sock_plain.close if @sock_plain && !@sock_plain.closed?
|
12
12
|
@sock_plain = nil
|
13
13
|
|
14
|
-
@sock_ssl.close if @sock_ssl
|
14
|
+
@sock_ssl.close if @sock_ssl && !@sock_ssl.closed?
|
15
15
|
@sock_ssl = nil
|
16
16
|
end
|
17
17
|
|
@@ -62,10 +62,12 @@ class Http2::Connection
|
|
62
62
|
puts "Http2: Reconnect." if @debug
|
63
63
|
|
64
64
|
#Open connection.
|
65
|
-
if @args[:proxy]
|
66
|
-
|
67
|
-
|
68
|
-
|
65
|
+
if @args[:proxy]
|
66
|
+
if @args[:proxy][:connect]
|
67
|
+
connect_proxy_connect
|
68
|
+
else
|
69
|
+
connect_proxy
|
70
|
+
end
|
69
71
|
else
|
70
72
|
puts "Http2: Opening socket connection to '#{@http2.host}:#{@http2.port}'." if @debug
|
71
73
|
@sock_plain = TCPSocket.new(@http2.host, @http2.port)
|
@@ -102,23 +104,39 @@ class Http2::Connection
|
|
102
104
|
@sock_plain.close if @sock_plain && !@sock_plain.closed?
|
103
105
|
end
|
104
106
|
|
105
|
-
def
|
106
|
-
puts "Http2: Initializing proxy
|
107
|
+
def connect_proxy_connect
|
108
|
+
puts "Http2: Initializing proxy connect to '#{@args[:host]}:#{@args[:port]}' through proxy '#{@args[:proxy][:host]}:#{@args[:proxy][:port]}'." if @debug
|
107
109
|
@sock_plain = TCPSocket.new(@args[:proxy][:host], @args[:proxy][:port])
|
108
110
|
|
109
|
-
|
110
|
-
|
111
|
+
connect = "CONNECT #{@args[:host]}:#{@args[:port]} HTTP/1.1#{@nl}"
|
112
|
+
puts "Http2: Sending connect: #{connect}" if @debug
|
113
|
+
@sock_plain.write(connect)
|
114
|
+
|
115
|
+
headers = {
|
116
|
+
"Host" => "#{@args[:host]}:#{@args[:port]}"
|
117
|
+
}
|
111
118
|
|
112
119
|
if @args[:proxy][:user] && @args[:proxy][:passwd]
|
113
|
-
|
114
|
-
|
115
|
-
|
120
|
+
headers["Proxy-Authorization"] = "Basic #{["#{@args[:proxy][:user]}:#{@args[:proxy][:passwd]}"].pack("m").chomp}"
|
121
|
+
end
|
122
|
+
|
123
|
+
headers.each do |key, value|
|
124
|
+
header = "#{key}: #{value}"
|
125
|
+
puts "Http2: Sending header to proxy: #{header}" if @debug
|
126
|
+
@sock_plain.write("#{header}#{@nl}")
|
116
127
|
end
|
117
128
|
|
118
129
|
@sock_plain.write(@nl)
|
119
130
|
|
120
|
-
res = @sock_plain.gets
|
121
|
-
raise res
|
131
|
+
res = @sock_plain.gets.to_s
|
132
|
+
raise "Couldn't connect through proxy: #{res}" unless res.match(/^http\/1\.(0|1)\s+200/i)
|
133
|
+
@sock_plain.gets
|
134
|
+
|
135
|
+
@proxy_connect = true
|
136
|
+
end
|
137
|
+
|
138
|
+
def proxy_connect?
|
139
|
+
@proxy_connect
|
122
140
|
end
|
123
141
|
|
124
142
|
def connect_proxy
|
@@ -131,8 +149,7 @@ class Http2::Connection
|
|
131
149
|
require "openssl" unless ::Kernel.const_defined?(:OpenSSL)
|
132
150
|
|
133
151
|
ssl_context = OpenSSL::SSL::SSLContext.new
|
134
|
-
|
135
|
-
|
152
|
+
ssl_context.verify_mode = OpenSSL::SSL::VERIFY_PEER unless @args[:ssl_skip_verify]
|
136
153
|
@sock_ssl = OpenSSL::SSL::SSLSocket.new(@sock_plain, ssl_context)
|
137
154
|
@sock_ssl.sync_close = true
|
138
155
|
@sock_ssl.connect
|
data/include/cookie.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
class Http2::Cookie
|
2
|
+
attr_reader :name, :value, :path, :expires_raw
|
3
|
+
|
4
|
+
def initialize(args)
|
5
|
+
@name, @value, @path, @expires_raw = args[:name], args[:value], args[:path], args[:expires]
|
6
|
+
end
|
7
|
+
|
8
|
+
def inspect
|
9
|
+
"#<Http2::Cookie name=#{@name} value=#{@value} path=#{@path}>"
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_s
|
13
|
+
inspect
|
14
|
+
end
|
15
|
+
|
16
|
+
def expires
|
17
|
+
@expires ||= Time.parse(@expires_raw) if @expires_raw
|
18
|
+
end
|
19
|
+
end
|
data/include/response_reader.rb
CHANGED
@@ -57,8 +57,8 @@ class Http2::ResponseReader
|
|
57
57
|
# Validate that the response is as it should be.
|
58
58
|
puts "Http2: Validating response." if @debug
|
59
59
|
|
60
|
-
|
61
|
-
raise "No status-code was received from the server. Headers: '#{@response.headers}' Body: '#{
|
60
|
+
unless @response.code
|
61
|
+
raise "No status-code was received from the server. Headers: '#{@response.headers}' Body: '#{@response.body}'."
|
62
62
|
end
|
63
63
|
|
64
64
|
@response.validate!
|
@@ -74,10 +74,10 @@ class Http2::ResponseReader
|
|
74
74
|
private
|
75
75
|
|
76
76
|
def check_and_follow_redirect
|
77
|
-
if
|
77
|
+
if redirect_response?
|
78
78
|
url, args = url_and_args_from_location
|
79
79
|
|
80
|
-
if
|
80
|
+
if redirect_using_same_connection?(args)
|
81
81
|
return @http2.get(url)
|
82
82
|
else
|
83
83
|
::Http2.new(args).get(url)
|
@@ -85,6 +85,19 @@ private
|
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
88
|
+
REDIRECT_CODES = [302, 303, 307]
|
89
|
+
def redirect_response?
|
90
|
+
REDIRECT_CODES.include?(@response.code.to_i) && @response.header?("location") && @http2.args[:follow_redirects]
|
91
|
+
end
|
92
|
+
|
93
|
+
def redirect_using_same_connection?(args)
|
94
|
+
if !args[:host] || args[:host] == @args[:host]
|
95
|
+
return true
|
96
|
+
else
|
97
|
+
return false
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
88
101
|
def url_and_args_from_location
|
89
102
|
uri = URI.parse(@response.header("location"))
|
90
103
|
url = uri.path
|
@@ -145,8 +158,8 @@ private
|
|
145
158
|
end
|
146
159
|
|
147
160
|
def parse_cookie(cookie_line)
|
148
|
-
::Http2::Utils.parse_set_cookies(cookie_line).each do |
|
149
|
-
@http2.cookies[
|
161
|
+
::Http2::Utils.parse_set_cookies(cookie_line).each do |cookie|
|
162
|
+
@http2.cookies[cookie.name] = cookie
|
150
163
|
end
|
151
164
|
end
|
152
165
|
|
data/include/utils.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
#This class holds various methods for encoding, decoding and parsing of HTTP-related stuff.
|
1
|
+
# This class holds various methods for encoding, decoding and parsing of HTTP-related stuff.
|
2
2
|
class Http2::Utils
|
3
|
-
#URL-encodes a string.
|
3
|
+
# URL-encodes a string.
|
4
4
|
def self.urlenc(string)
|
5
5
|
#Thanks to CGI framework
|
6
6
|
string.to_s.gsub(/([^ a-zA-Z0-9_.-]+)/) do
|
@@ -8,7 +8,7 @@ class Http2::Utils
|
|
8
8
|
end.tr(' ', '+')
|
9
9
|
end
|
10
10
|
|
11
|
-
#URL-decodes a string.
|
11
|
+
# URL-decodes a string.
|
12
12
|
def self.urldec(string)
|
13
13
|
#Thanks to CGI framework
|
14
14
|
str = string.to_s.tr('+', ' ').gsub(/((?:%[0-9a-fA-F]{2})+)/) do
|
@@ -16,25 +16,35 @@ class Http2::Utils
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
#Parses a cookies-string and returns them in an array.
|
19
|
+
# Parses a cookies-string and returns them in an array.
|
20
20
|
def self.parse_set_cookies(str)
|
21
|
-
str =
|
22
|
-
return [] if str.
|
23
|
-
args = {}
|
21
|
+
str = "#{str}"
|
22
|
+
return [] if str.empty?
|
24
23
|
cookie_start_regex = /^(.+?)=(.*?)(;\s*|$)/
|
25
24
|
|
26
25
|
match = str.match(cookie_start_regex)
|
27
|
-
raise "Could not match cookie: '#{str}'
|
26
|
+
raise "Could not match cookie: '#{str}'" unless match
|
28
27
|
str.gsub!(cookie_start_regex, "")
|
29
28
|
|
30
|
-
|
31
|
-
|
29
|
+
cookie_data = {
|
30
|
+
name: urldec(match[1].to_s),
|
31
|
+
value: self.urldec(match[2].to_s)
|
32
|
+
}
|
32
33
|
|
33
34
|
while match = str.match(/(.+?)=(.*?)(;\s*|$)/)
|
34
35
|
str = str.gsub(match[0], "")
|
35
|
-
|
36
|
+
key = match[1].to_s.downcase
|
37
|
+
value = match[2].to_s
|
38
|
+
|
39
|
+
if key == "path" || key == "expires"
|
40
|
+
cookie_data[key.to_sym] = value
|
41
|
+
else
|
42
|
+
cookie_data[key] = value
|
43
|
+
end
|
36
44
|
end
|
37
45
|
|
38
|
-
|
46
|
+
cookie = Http2::Cookie.new(cookie_data)
|
47
|
+
|
48
|
+
return [cookie]
|
39
49
|
end
|
40
50
|
end
|
data/lib/http2.rb
CHANGED
@@ -15,16 +15,16 @@ require "string-cases"
|
|
15
15
|
# print "#{res.headers}"
|
16
16
|
# end
|
17
17
|
class Http2
|
18
|
-
#Autoloader for subclasses.
|
18
|
+
# Autoloader for subclasses.
|
19
19
|
def self.const_missing(name)
|
20
20
|
require "#{File.dirname(__FILE__)}/../include/#{::StringCases.camel_to_snake(name)}.rb"
|
21
21
|
return Http2.const_get(name)
|
22
22
|
end
|
23
23
|
|
24
|
-
#Converts a URL to "is.gd"-short-URL.
|
24
|
+
# Converts a URL to "is.gd"-short-URL.
|
25
25
|
def self.isgdlink(url)
|
26
26
|
Http2.new(host: "is.gd") do |http|
|
27
|
-
resp = http.get("
|
27
|
+
resp = http.get("api.php?longurl=#{url}")
|
28
28
|
return resp.body
|
29
29
|
end
|
30
30
|
end
|
@@ -32,7 +32,7 @@ class Http2
|
|
32
32
|
attr_reader :autostate, :connection, :cookies, :args, :debug, :mutex, :resp, :raise_errors, :nl
|
33
33
|
attr_accessor :keepalive_max, :keepalive_timeout
|
34
34
|
|
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
|
+
VALID_ARGUMENTS_INITIALIZE = [:host, :port, :skip_port_in_host_header, :ssl, :ssl_skip_verify, :nl, :user_agent, :raise_errors, :follow_redirects, :debug, :encoding_gzip, :autostate, :basic_auth, :extra_headers, :proxy]
|
36
36
|
def initialize(args = {})
|
37
37
|
@args = parse_init_args(args)
|
38
38
|
set_default_values
|
@@ -78,7 +78,7 @@ class Http2
|
|
78
78
|
@connection = ::Http2::Connection.new(self)
|
79
79
|
end
|
80
80
|
|
81
|
-
#Destroys the object unsetting all variables and closing all sockets.
|
81
|
+
# Destroys the object unsetting all variables and closing all sockets.
|
82
82
|
#===Examples
|
83
83
|
# http.destroy
|
84
84
|
def destroy
|
@@ -94,26 +94,22 @@ class Http2
|
|
94
94
|
@connection = nil
|
95
95
|
end
|
96
96
|
|
97
|
-
#Forces various stuff into arguments-hash like URL from original arguments and enables single-string-shortcuts and more.
|
97
|
+
# Forces various stuff into arguments-hash like URL from original arguments and enables single-string-shortcuts and more.
|
98
98
|
def parse_args(*args)
|
99
99
|
if args.length == 1 && args.first.is_a?(String)
|
100
100
|
args = {url: args.first}
|
101
|
-
elsif args.length
|
102
|
-
raise "Couldnt parse arguments."
|
103
|
-
elsif args.is_a?(Array) && args.length == 1
|
101
|
+
elsif args.length == 1
|
104
102
|
args = args.first
|
105
103
|
else
|
106
|
-
raise "Invalid arguments: '#{args.class.name}'
|
104
|
+
raise "Invalid arguments: '#{args.class.name}'"
|
107
105
|
end
|
108
106
|
|
109
|
-
|
110
|
-
raise "Invalid URL: '#{args[:url]}'."
|
111
|
-
end
|
107
|
+
raise "Invalid URL: '#{args[:url]}'" unless args[:url].to_s.split("\n").length == 1
|
112
108
|
|
113
109
|
return args
|
114
110
|
end
|
115
111
|
|
116
|
-
#Returns a result-object based on the arguments.
|
112
|
+
# Returns a result-object based on the arguments.
|
117
113
|
#===Examples
|
118
114
|
# res = http.get("somepage.html")
|
119
115
|
# print res.body #=> <String>-object containing the HTML gotten.
|
@@ -130,7 +126,7 @@ class Http2
|
|
130
126
|
end
|
131
127
|
end
|
132
128
|
|
133
|
-
#Returns the default headers for a request.
|
129
|
+
# Returns the default headers for a request.
|
134
130
|
#===Examples
|
135
131
|
# headers_hash = http.default_headers
|
136
132
|
# print "#{headers_hash}"
|
@@ -139,15 +135,10 @@ class Http2
|
|
139
135
|
|
140
136
|
headers = {
|
141
137
|
"Connection" => "Keep-Alive",
|
142
|
-
"User-Agent" => @uagent
|
138
|
+
"User-Agent" => @uagent,
|
139
|
+
"Host" => host_header
|
143
140
|
}
|
144
141
|
|
145
|
-
#Possible to give custom host-argument.
|
146
|
-
host = args[:host] || self.host
|
147
|
-
port = args[:port] || self.port
|
148
|
-
|
149
|
-
headers["Host"] = "#{host}" # Copy host string to avoid changing the original string if port has been given!
|
150
|
-
headers["Host"] << ":#{port}" if port && ![80, 443].include?(port.to_i) && !@args[:skip_port_in_host_header]
|
151
142
|
headers["Accept-Encoding"] = "gzip" if @args[:encoding_gzip]
|
152
143
|
|
153
144
|
if @args[:basic_auth]
|
@@ -155,26 +146,32 @@ class Http2
|
|
155
146
|
headers["Authorization"] = "Basic #{Base64.encode64("#{@args[:basic_auth][:user]}:#{@args[:basic_auth][:passwd]}").strip}"
|
156
147
|
end
|
157
148
|
|
149
|
+
if @args[:proxy] && @args[:proxy][:user] && @args[:proxy][:passwd] && !@connection.proxy_connect?
|
150
|
+
require "base64" unless ::Kernel.const_defined?(:Base64)
|
151
|
+
puts "Http2: Adding proxy auth header to request" if @debug
|
152
|
+
headers["Proxy-Authorization"] = "Basic #{Base64.encode64("#{@args[:proxy][:user]}:#{@args[:proxy][:passwd]}").strip}"
|
153
|
+
end
|
154
|
+
|
158
155
|
headers.merge!(@args[:extra_headers]) if @args[:extra_headers]
|
159
156
|
headers.merge!(args[:headers]) if args[:headers]
|
160
157
|
return headers
|
161
158
|
end
|
162
159
|
|
163
|
-
#Posts to a certain page.
|
160
|
+
# Posts to a certain page.
|
164
161
|
#===Examples
|
165
162
|
# res = http.post("login.php", {"username" => "John Doe", "password" => 123)
|
166
163
|
def post(args)
|
167
164
|
::Http2::PostRequest.new(self, args).execute
|
168
165
|
end
|
169
166
|
|
170
|
-
#Posts to a certain page using the multipart-method.
|
167
|
+
# Posts to a certain page using the multipart-method.
|
171
168
|
#===Examples
|
172
169
|
# res = http.post_multipart("upload.php", {"normal_value" => 123, "file" => Tempfile.new(?)})
|
173
170
|
def post_multipart(*args)
|
174
171
|
::Http2::PostMultipartRequest.new(self, *args).execute
|
175
172
|
end
|
176
173
|
|
177
|
-
#Returns a header-string which normally would be used for a request in the given state.
|
174
|
+
# Returns a header-string which normally would be used for a request in the given state.
|
178
175
|
def header_str(headers_hash, args = {})
|
179
176
|
headers_hash["Cookie"] = cookie_header_string
|
180
177
|
|
@@ -190,30 +187,33 @@ class Http2
|
|
190
187
|
cstr = ""
|
191
188
|
|
192
189
|
first = true
|
193
|
-
@cookies.each do |cookie_name,
|
190
|
+
@cookies.each do |cookie_name, cookie|
|
194
191
|
cstr << "; " unless first
|
195
192
|
first = false if first
|
196
|
-
|
197
|
-
|
198
|
-
name = cookie_data["name"]
|
199
|
-
value = cookie_data["value"]
|
200
|
-
else
|
201
|
-
name = cookie_name
|
202
|
-
value = cookie_data
|
203
|
-
end
|
204
|
-
|
205
|
-
raise "Unexpected lines: #{value.lines.to_a.length}." if value.lines.to_a.length != 1
|
206
|
-
cstr << "#{Http2::Utils.urlenc(name)}=#{Http2::Utils.urlenc(value)}"
|
193
|
+
ensure_single_lines([cookie.name, cookie.value])
|
194
|
+
cstr << "#{Http2::Utils.urlenc(cookie.name)}=#{Http2::Utils.urlenc(cookie.value)}"
|
207
195
|
end
|
208
196
|
|
209
197
|
return cstr
|
210
198
|
end
|
211
199
|
|
200
|
+
def cookie(name)
|
201
|
+
name = name.to_s
|
202
|
+
return @cookies.fetch(name) if @cookies.key?(name)
|
203
|
+
raise "No cookie by that name: '#{name}' in '#{@cookies.keys.join(", ")}'"
|
204
|
+
end
|
205
|
+
|
206
|
+
def ensure_single_lines(*strings)
|
207
|
+
strings.each do |string|
|
208
|
+
raise "More than one line: #{string}." unless string.to_s.lines.to_a.length == 1
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
212
|
def on_content_call(args, str)
|
213
213
|
args[:on_content].call(str) if args.key?(:on_content)
|
214
214
|
end
|
215
215
|
|
216
|
-
#Reads the response after posting headers and data.
|
216
|
+
# Reads the response after posting headers and data.
|
217
217
|
#===Examples
|
218
218
|
# res = http.read_response
|
219
219
|
def read_response(args = {})
|
@@ -230,7 +230,17 @@ class Http2
|
|
230
230
|
|
231
231
|
private
|
232
232
|
|
233
|
-
|
233
|
+
def host_header
|
234
|
+
#Possible to give custom host-argument.
|
235
|
+
host = args[:host] || self.host
|
236
|
+
port = args[:port] || self.port
|
237
|
+
|
238
|
+
host_header_string = "#{host}" # Copy host string to avoid changing the original string if port has been given!
|
239
|
+
host_header_string << ":#{port}" if port && ![80, 443].include?(port.to_i) && !@args[:skip_port_in_host_header]
|
240
|
+
return host_header_string
|
241
|
+
end
|
242
|
+
|
243
|
+
# Registers the states from a result.
|
234
244
|
def autostate_register(res)
|
235
245
|
puts "Http2: Running autostate-register on result." if @debug
|
236
246
|
@autostate_values.clear
|
@@ -247,7 +257,7 @@ private
|
|
247
257
|
raise "No states could be found." if @autostate_values.empty?
|
248
258
|
end
|
249
259
|
|
250
|
-
#Sets the states on the given post-hash.
|
260
|
+
# Sets the states on the given post-hash.
|
251
261
|
def autostate_set_on_post_hash(phash)
|
252
262
|
phash.merge!(@autostate_values)
|
253
263
|
end
|
@@ -260,6 +270,8 @@ private
|
|
260
270
|
raise "Invalid key: '#{key}'." unless VALID_ARGUMENTS_INITIALIZE.include?(key)
|
261
271
|
end
|
262
272
|
|
273
|
+
args[:proxy][:connect] = true if args[:proxy] && !args[:proxy].key?(:connect) && args[:ssl]
|
274
|
+
|
263
275
|
raise "No host was given." unless args[:host]
|
264
276
|
return args
|
265
277
|
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
|
+
res = http.get("cookie_test.rhtml")
|
9
|
+
http.cookies.length.should eq 2
|
10
|
+
|
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
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
metadata
CHANGED
@@ -1,27 +1,27 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: http2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.31
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kasper Johansen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-05-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: string-cases
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
@@ -84,14 +84,14 @@ dependencies:
|
|
84
84
|
name: hayabusa
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - "
|
87
|
+
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: 0.0.25
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- - "
|
94
|
+
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: 0.0.25
|
97
97
|
- !ruby/object:Gem::Dependency
|
@@ -135,6 +135,7 @@ files:
|
|
135
135
|
- README.md
|
136
136
|
- Rakefile
|
137
137
|
- include/connection.rb
|
138
|
+
- include/cookie.rb
|
138
139
|
- include/errors.rb
|
139
140
|
- include/get_request.rb
|
140
141
|
- include/post_data_generator.rb
|
@@ -146,12 +147,14 @@ files:
|
|
146
147
|
- include/utils.rb
|
147
148
|
- lib/http2.rb
|
148
149
|
- spec/helpers.rb
|
150
|
+
- spec/http2/cookies_spec.rb
|
149
151
|
- spec/http2/post_data_generator_spec.rb
|
150
152
|
- spec/http2/response_spec.rb
|
151
153
|
- spec/http2/url_builder_spec.rb
|
152
154
|
- spec/http2_spec.rb
|
153
155
|
- spec/spec_helper.rb
|
154
156
|
- spec/spec_root/content_type_test.rhtml
|
157
|
+
- spec/spec_root/cookie_test.rhtml
|
155
158
|
- spec/spec_root/json_test.rhtml
|
156
159
|
- spec/spec_root/multipart_test.rhtml
|
157
160
|
- spec/spec_root/redirect_test.rhtml
|
@@ -175,19 +178,21 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
175
178
|
version: '0'
|
176
179
|
requirements: []
|
177
180
|
rubyforge_project:
|
178
|
-
rubygems_version: 2.
|
181
|
+
rubygems_version: 2.2.2
|
179
182
|
signing_key:
|
180
183
|
specification_version: 4
|
181
184
|
summary: A lightweight framework for doing http-connections in Ruby. Supports cookies,
|
182
185
|
keep-alive, compressing and much more.
|
183
186
|
test_files:
|
184
|
-
- spec/
|
187
|
+
- spec/helpers.rb
|
188
|
+
- spec/http2/cookies_spec.rb
|
185
189
|
- spec/http2/post_data_generator_spec.rb
|
186
|
-
- spec/http2/url_builder_spec.rb
|
187
190
|
- spec/http2/response_spec.rb
|
188
|
-
- spec/
|
191
|
+
- spec/http2/url_builder_spec.rb
|
192
|
+
- spec/http2_spec.rb
|
193
|
+
- spec/spec_helper.rb
|
194
|
+
- spec/spec_root/content_type_test.rhtml
|
195
|
+
- spec/spec_root/cookie_test.rhtml
|
189
196
|
- spec/spec_root/json_test.rhtml
|
190
197
|
- spec/spec_root/multipart_test.rhtml
|
191
|
-
- spec/spec_root/
|
192
|
-
- spec/helpers.rb
|
193
|
-
- spec/spec_helper.rb
|
198
|
+
- spec/spec_root/redirect_test.rhtml
|