http2 0.0.30 → 0.0.31

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e7a58ef37e262df0923fbbcabfbb596dda05eb4c
4
- data.tar.gz: 4d9b2368eeb6a303ea63e392f15883429ffc0ab7
3
+ metadata.gz: 00dd7c4f177f2a7c84ef8f9ef463fe6f2675a400
4
+ data.tar.gz: 7c28395bf02c20a50d2b8633e6ddd8156c8972f3
5
5
  SHA512:
6
- metadata.gz: e39cd726b145f5143567b7a54f0b8e79f77668a7ac8011351e817b99b4487783a91197b7440cb2ad1a3659268f8259eb5da73c5996e2d4ce2c110853aa035fbe
7
- data.tar.gz: 971fd5c395b68e5e4c0d83bf57d6a8c5a6abb7f63afaaf8a8246ebd65070f7144df7739759989c8ae56b60011965fdb43ba6ce1c67215bc1dc483243a0d927e9
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/53bd3eef2e23bdcb03c0df9e/badge/master)](https://www.shippable.com/projects/53bd3eef2e23bdcb03c0df9e)
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.close
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.
@@ -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 and !@sock.closed?
8
+ @sock.close if @sock && !@sock.closed?
9
9
  @sock = nil
10
10
 
11
- @sock_plain.close if @sock_plain and !@sock_plain.closed?
11
+ @sock_plain.close if @sock_plain && !@sock_plain.closed?
12
12
  @sock_plain = nil
13
13
 
14
- @sock_ssl.close if @sock_ssl and !@sock_ssl.closed?
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] && @args[:ssl]
66
- connect_proxy_ssl
67
- elsif @args[:proxy]
68
- connect_proxy
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 connect_proxy_ssl
106
- puts "Http2: Initializing proxy stuff." if @debug
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
- @sock_plain.write("CONNECT #{@args[:host]}:#{@args[:port]} HTTP/1.0#{@nl}")
110
- @sock_plain.write("User-Agent: #{@uagent}#{@nl}")
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
- credential = ["#{@args[:proxy][:user]}:#{@args[:proxy][:passwd]}"].pack("m")
114
- credential.delete!("\r\n")
115
- @sock_plain.write("Proxy-Authorization: Basic #{credential}#{@nl}")
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 if res.to_s.downcase != "http/1.0 200 connection established#{@nl}"
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
- #ssl_context.verify_mode = OpenSSL::SSL::VERIFY_PEER
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
@@ -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
@@ -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
- if !@response.code
61
- raise "No status-code was received from the server. Headers: '#{@response.headers}' Body: '#{resp.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 (@response.code == "302" || @response.code == "303" || @response.code == "307") && @response.header?("location") && @http2.args[:follow_redirects]
77
+ if redirect_response?
78
78
  url, args = url_and_args_from_location
79
79
 
80
- if !args[:host] || args[:host] == @args[:host]
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 |cookie_data|
149
- @http2.cookies[cookie_data["name"]] = cookie_data
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
 
@@ -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 = String.new(str.to_s)
22
- return [] if str.length <= 0
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}'." if !match
26
+ raise "Could not match cookie: '#{str}'" unless match
28
27
  str.gsub!(cookie_start_regex, "")
29
28
 
30
- args["name"] = self.urldec(match[1].to_s)
31
- args["value"] = self.urldec(match[2].to_s)
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
- args[match[1].to_s.downcase] = match[2].to_s
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
- return [args]
46
+ cookie = Http2::Cookie.new(cookie_data)
47
+
48
+ return [cookie]
39
49
  end
40
50
  end
@@ -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("/api.php?longurl=#{url}")
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 >= 2
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
- if args[:url].to_s.split("\n").length != 1
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, cookie_data|
190
+ @cookies.each do |cookie_name, cookie|
194
191
  cstr << "; " unless first
195
192
  first = false if first
196
-
197
- if cookie_data.is_a?(Hash)
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
- #Registers the states from a result.
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
@@ -0,0 +1,8 @@
1
+ <%
2
+ _hb.cookie(
3
+ "name" => "TestCookie",
4
+ "value" => "TestValue",
5
+ "expires" => Time.new + 3600,
6
+ "path" => "/"
7
+ )
8
+ %>
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.30
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-03-20 00:00:00.000000000 Z
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.4.0
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/http2_spec.rb
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/spec_root/redirect_test.rhtml
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/content_type_test.rhtml
192
- - spec/helpers.rb
193
- - spec/spec_helper.rb
198
+ - spec/spec_root/redirect_test.rhtml