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 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