emmy-http-client 0.1.4 → 0.1.5

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: 35283fd9ab14415f3033f0f384cf8f2596a1c21c
4
- data.tar.gz: a93d21ba7741067a021714a507c0d7e53b704bda
3
+ metadata.gz: 2c7fc57b8e4db179543db0f0c952b9a83ac21c21
4
+ data.tar.gz: e67dc588346d1b4d4890c2f8e3b5108c66a635de
5
5
  SHA512:
6
- metadata.gz: d93a2971c251fcc46f7b067249ad4a9e23ad8863fefc3a99c4677dbbccb1a08e2c1a233f7f23ee1718e0359538667ae0680df2586785e721fd17766ee891248d
7
- data.tar.gz: 1c10235bcae47cc4b7135398a754caf9a677f81489e41b34902bdd01303c38ddfb08dca30c21bc414dc248d5e3b139c4619d95c925a1a24aa2c970f08306abd6
6
+ metadata.gz: b41434ae7b141ff5dd5792d715a4634a12d89fb0f1fca5f486c0021f46942ada2635c15c3d5e0f2945fb6912c6f540d092c3c28be8d64762eb398beca5384dc8
7
+ data.tar.gz: d531c99e24c15f9824730031635a074da2bc16a395c6d6e881e7df36384c099055b9a557bf4b88110e2c0c8e5dd8ff267841e087b29b71c3412230ed17c48383
data/.rspec CHANGED
@@ -1,2 +1,3 @@
1
1
  --format documentation
2
2
  --color
3
+ --tag ~skip
data/Gemfile CHANGED
@@ -2,3 +2,5 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in emmy-http-client.gemspec
4
4
  gemspec
5
+
6
+ gem 'emmy-http', path: '~/Dropbox/Projects/emmy/emmy-http'
@@ -20,10 +20,11 @@ Gem::Specification.new do |spec|
20
20
  spec.require_paths = ["lib"]
21
21
 
22
22
  spec.add_dependency "http_parser.rb", "0.6.0"
23
+ spec.add_dependency "addressable", ">= 2.3.8"
23
24
  spec.add_dependency "event_object", "~> 0.9.1"
24
25
  spec.add_dependency "fibre", "~> 0.9.7"
25
26
  spec.add_dependency "emmy-machine", "~> 0.1.7"
26
- spec.add_dependency "emmy-http", "~> 0.1.6"
27
+ #spec.add_dependency "emmy-http", "~> 0.1.7"
27
28
 
28
29
  spec.add_development_dependency "bundler", "~> 1.9"
29
30
  spec.add_development_dependency "rake", "~> 10.0"
@@ -1,3 +1,4 @@
1
+ require 'base64'
1
2
  require 'event_object'
2
3
  require 'emmy_http'
3
4
  require 'fibre'
@@ -8,7 +9,7 @@ require "emmy_http/client/cookie"
8
9
  require "emmy_http/client/parser"
9
10
  require "emmy_http/client/adapter"
10
11
  require "emmy_http/client/client"
11
- require "emmy_http/client/encoding"
12
+ require "emmy_http/client/encoders"
12
13
 
13
14
  module EmmyHttp
14
15
  module Client
@@ -16,5 +17,10 @@ module EmmyHttp
16
17
  HTTP_VERSION = 'HTTP/1.1'.freeze
17
18
 
18
19
  autoload :Monitor, "emmy_http/client/monitor"
20
+
21
+ module Decoders
22
+ autoload :Deflate, "emmy_http/client/decoders/deflate"
23
+ autoload :GZip, "emmy_http/client/decoders/gzip"
24
+ end
19
25
  end
20
26
  end
@@ -14,6 +14,7 @@ module EmmyHttp
14
14
  attr_accessor :adapter
15
15
  attr_accessor :parser
16
16
  attr_accessor :stop_reason
17
+ attr_accessor :decoder
17
18
 
18
19
  attr_accessor :redirects
19
20
 
@@ -46,31 +47,25 @@ module EmmyHttp
46
47
  headers: headers,
47
48
  body: ''
48
49
  )
50
+ client.decoder = new_decoder_by_encoding(headers['Content-Encoding']) if request.decoding
49
51
  operation.head!(response, operation, connection)
50
52
  #parser.reset = true if request.no_body?
51
53
  end
52
54
 
53
55
  parser.on :body do |chunk|
54
- response.data!(chunk)
56
+ response.data!(client.decoder ? (client.decoder.decompress(chunk) || '') : chunk)
55
57
  end
56
58
 
57
59
  parser.on :completed do
58
60
  client.response.finish
59
-
60
- if request.keep_alive?
61
- change_state(:success)
62
- dettach(conn)
63
- operation.success!(response, operation, connection)
64
- else
65
- client.stop
66
- end
61
+ request.keep_alive? ? finalize : client.stop
67
62
  end
68
63
 
69
64
  change_state(:wait_connect)
70
65
  end
71
66
 
72
67
  def connect
73
- connection.start_tls(request.ssl ? request.ssl.serializable_hash : {}) if request.ssl?
68
+ connection.start_tls(request.ssl ? request.ssl.serializable_hash : {}) if ssl?
74
69
  send_request
75
70
  change_state(:wait_response)
76
71
  end
@@ -96,35 +91,32 @@ module EmmyHttp
96
91
 
97
92
  if response && response.redirection?
98
93
  change_state(:redirect)
99
- self.url = URI(response.location)
94
+ self.url = url + response.location
100
95
  self.response = nil
101
96
  parser.reset!
102
97
  operation.reconnect
103
98
  return
104
99
  end
105
100
 
106
- if response && response.finished?
107
- change_state(:success)
108
- dettach(connection)
109
- operation.success!(response, operation, connection)
110
- else
111
- change_state(:catch_error)
112
- operation.error!(reason.new.to_s || 'Invalid response')
113
- end
101
+ finalize(reason)
114
102
  end
115
103
 
116
104
  def send_request
117
105
  headers = {}
118
106
  body = prepare_body(headers)
107
+ body = Encoders.encode_body(request.headers["Content-Encoding"], body) if request.encoding?
119
108
 
120
109
  prepare_headers(headers)
121
110
  send_http_request(headers, body)
122
111
  end
123
112
 
124
113
  def prepare_url
125
- @url = request.url
114
+ @url = request.real_url
115
+ raise 'relative url' if @url.relative?
116
+
117
+ @url.normalize!
126
118
  @url.path = request.path.to_s if request.path
127
- @url.query = request.query.is_a?(Hash) ? Encoding.query(request.query) : request.query.to_s if request.query
119
+ @url.query = request.query.is_a?(Hash) ? Encoders.query(request.query) : request.query.to_s if request.query
128
120
  end
129
121
 
130
122
  def prepare_body(headers)
@@ -137,8 +129,8 @@ module EmmyHttp
137
129
  body_text
138
130
 
139
131
  elsif form
140
- form_encoded = form.is_a?(String) ? form : Encoding.www_form(form)
141
- body_text = Encoding.rfc3986(form_encoded)
132
+ form_encoded = form.is_a?(String) ? form : Encoders.www_form(form)
133
+ body_text = Encoders.rfc3986(form_encoded)
142
134
  headers['Content-Type'] = 'application/x-www-form-urlencoded'
143
135
  headers['Content-Length'] = body_text.bytesize
144
136
  body_text
@@ -165,9 +157,9 @@ module EmmyHttp
165
157
 
166
158
  # TODO: cookie
167
159
 
168
- headers['Connection'] = 'close' unless request.keep_alive?
169
- headers['User-Agent'] = Client::USER_AGENT unless headers.key? 'User-Agent'
170
- headers['Authorization'] = url.userinfo.split(/:/, 2) if url.userinfo
160
+ headers['Connection'] = 'close' unless request.keep_alive?
161
+ headers['User-Agent'] = Client::USER_AGENT unless headers.key? 'User-Agent'
162
+ headers['Authorization'] ||= Encoders.encode_auth(url.userinfo) if url.userinfo
171
163
 
172
164
  unless headers.key? 'Host'
173
165
  headers['Host'] = url.host
@@ -191,10 +183,26 @@ module EmmyHttp
191
183
  connection.send_stream_file_data request.file if request.file
192
184
  end
193
185
 
186
+ def finalize(reason=nil)
187
+ dettach(connection)
188
+ if response && response.finished?
189
+ change_state(:success)
190
+ response.data!(decoder.finalize || '') if decoder
191
+ operation.success!(response, operation, connection)
192
+ else
193
+ change_state(:catch_error)
194
+ operation.error!(reason ? reason.new.to_s : 'Invalid response')
195
+ end
196
+ end
197
+
194
198
  def url_path
195
199
  url.query ? '/' + url.path + '?' + url.query : '/' + url.path
196
200
  end
197
201
 
202
+ def ssl?
203
+ request.ssl || url.scheme == 'https' || url.port == 443
204
+ end
205
+
198
206
  def stop(reason=nil)
199
207
  @stop_reason ||= reason
200
208
  connection.close_connection if connection
@@ -217,8 +225,19 @@ module EmmyHttp
217
225
  stop_listen conn, :close
218
226
  end
219
227
 
228
+ def new_decoder_by_encoding(encoding)
229
+ case encoding
230
+ when 'deflate', 'compressed'
231
+ EmmyHttp::Client::Decoders::Deflate.new
232
+ when 'gzip'
233
+ EmmyHttp::Client::Decoders::GZip.new
234
+ else
235
+ nil
236
+ end
237
+ end
238
+
220
239
  def to_a
221
- ["tcp://#{url.host}:#{url.port}", connection || EmmyMachine::Connection, method(:initialize_connection), self]
240
+ ["tcp://#{url.host}:#{url.port || url.default_port}", connection || EmmyMachine::Connection, method(:initialize_connection), self]
222
241
  end
223
242
 
224
243
  #<<<
@@ -0,0 +1,24 @@
1
+ require 'zlib'
2
+
3
+ module EmmyHttp
4
+ # rfc1951
5
+ class Client::Decoders::Deflate
6
+ def initialize
7
+ @i_gz = Zlib::Inflate.new(Zlib::MAX_WBITS)
8
+ end
9
+
10
+ def decompress(chunk)
11
+ @i_gz.inflate(chunk)
12
+ rescue Zlib::Error => e
13
+ raise EmmyHttp::DecoderError, e
14
+ end
15
+
16
+ def finalize
17
+ decompress(nil)
18
+ ensure
19
+ @i_gz.close
20
+ end
21
+
22
+ #<<<
23
+ end
24
+ end
@@ -1,5 +1,5 @@
1
1
  module EmmyHttp
2
- module Encoding
2
+ module Encoders
3
3
  extend self
4
4
 
5
5
  def escape(str)
@@ -26,6 +26,31 @@ module EmmyHttp
26
26
  end
27
27
  end
28
28
 
29
+ def encode_auth(userinfo)
30
+ "Basic #{Base64.strict_encode64(userinfo)}"
31
+ end
32
+
33
+ def encode_body(encoding, body)
34
+ require 'zlib'
35
+ require 'stringio'
36
+
37
+ case encoding
38
+ when "gzip"
39
+ wio = StringIO.new("w")
40
+ begin
41
+ w_gz = Zlib::GzipWriter.new(wio)
42
+ w_gz.write(body)
43
+ rescue
44
+ raise EmmyHttp::EncoderError
45
+ ensure
46
+ w_gz.close
47
+ end
48
+ wio.string
49
+ else
50
+ body
51
+ end
52
+ end
53
+
29
54
  #<<<
30
55
  end
31
56
  end
@@ -1,5 +1,5 @@
1
1
  module EmmyHttp
2
2
  module Client
3
- VERSION = "0.1.4"
3
+ VERSION = "0.1.5"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: emmy-http-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - inre
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-04-22 00:00:00.000000000 Z
11
+ date: 2015-04-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: http_parser.rb
@@ -25,61 +25,61 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.6.0
27
27
  - !ruby/object:Gem::Dependency
28
- name: event_object
28
+ name: addressable
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 0.9.1
33
+ version: 2.3.8
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: 0.9.1
40
+ version: 2.3.8
41
41
  - !ruby/object:Gem::Dependency
42
- name: fibre
42
+ name: event_object
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 0.9.7
47
+ version: 0.9.1
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 0.9.7
54
+ version: 0.9.1
55
55
  - !ruby/object:Gem::Dependency
56
- name: emmy-machine
56
+ name: fibre
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 0.1.7
61
+ version: 0.9.7
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 0.1.7
68
+ version: 0.9.7
69
69
  - !ruby/object:Gem::Dependency
70
- name: emmy-http
70
+ name: emmy-machine
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 0.1.6
75
+ version: 0.1.7
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 0.1.6
82
+ version: 0.1.7
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: bundler
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -128,7 +128,8 @@ files:
128
128
  - lib/emmy_http/client/adapter.rb
129
129
  - lib/emmy_http/client/client.rb
130
130
  - lib/emmy_http/client/cookie.rb
131
- - lib/emmy_http/client/encoding.rb
131
+ - lib/emmy_http/client/decoders/deflate.rb
132
+ - lib/emmy_http/client/encoders.rb
132
133
  - lib/emmy_http/client/monitor.rb
133
134
  - lib/emmy_http/client/parser.rb
134
135
  - lib/emmy_http/client/version.rb