alovak-network 1.1.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/network.rb CHANGED
@@ -1,11 +1,8 @@
1
+ require 'benchmark'
1
2
  require 'net/https'
2
3
  require 'network/connection'
3
- module Network
4
- class Error < Exception
5
- end
6
-
7
- VERSION = '1.0.0'
8
4
 
5
+ module Network
9
6
  def self.post(url, data)
10
7
  Connection.new(url).post(data)
11
8
  end
@@ -1,4 +1,18 @@
1
1
  module Network
2
+ class Error < Exception
3
+ end
4
+
5
+ class ResponseError < Error
6
+ attr_reader :response
7
+ def initialize(response)
8
+ @response = response
9
+ end
10
+
11
+ def to_s
12
+ "Failed with #{@response.code} #{@response.message if @response.respond_to?(:message)}"
13
+ end
14
+ end
15
+
2
16
  class Connection
3
17
  attr_reader :uri, :pem
4
18
 
@@ -22,17 +36,14 @@ module Network
22
36
  end
23
37
 
24
38
  def post(data)
25
- begin
39
+ try_request do
26
40
  log_request(data)
27
- http.post(uri.path, data, post_headers(data))
28
- rescue Timeout::Error, Errno::ETIMEDOUT, Timeout::ExitException
29
- raise Error, "The connection to the remote server is timed out"
30
- rescue EOFError
31
- raise Error, "The connection to the remote server was dropped"
32
- rescue Errno::ECONNRESET, Errno::ECONNABORTED
33
- raise Error, "The remote server reset the connection"
34
- rescue Errno::ECONNREFUSED
35
- raise Error, "The connection was refused by the remote server"
41
+ response = nil
42
+ ms = Benchmark.realtime do
43
+ response = http.post(uri.path, data, post_headers(data))
44
+ end
45
+ log_response(response, ms)
46
+ handle_response(response)
36
47
  end
37
48
  end
38
49
 
@@ -55,9 +66,32 @@ module Network
55
66
  http
56
67
  end
57
68
 
69
+ def handle_response(response)
70
+ case response.code.to_i
71
+ when 200...300
72
+ response.body
73
+ else
74
+ raise ResponseError.new(response)
75
+ end
76
+ end
77
+
78
+ def try_request(&block)
79
+ begin
80
+ block.call
81
+ rescue Timeout::Error, Errno::ETIMEDOUT, Timeout::ExitException
82
+ raise Error, "The connection to the remote server is timed out"
83
+ rescue EOFError
84
+ raise Error, "The connection to the remote server was dropped"
85
+ rescue Errno::ECONNRESET, Errno::ECONNABORTED
86
+ raise Error, "The remote server reset the connection"
87
+ rescue Errno::ECONNREFUSED
88
+ raise Error, "The connection was refused by the remote server"
89
+ end
90
+ end
91
+
58
92
  def post_headers(data)
59
93
  @headers['Content-Type'] ||= 'application/x-www-form-urlencoded'
60
- @headers['Content-Length'] ||= data.size.to_s
94
+ @headers['Content-Length'] ||= data.bytesize.to_s
61
95
  @headers
62
96
  end
63
97
 
@@ -105,9 +139,9 @@ module Network
105
139
  log (request_filter ? request_filter.call(data) : data)
106
140
  end
107
141
 
108
- def log_response(data)
109
- log "<---"
110
- log (response_filter ? response_filter.call(data) : data)
142
+ def log_response(response, ms_time = -1)
143
+ log "<-- %s %s (%d bytes %.2fms)" % [response.code, response.message, (response.body ? response.body.bytesize : 0), ms_time]
144
+ log (response_filter ? response_filter.call(response.body) : response.body) if response.body
111
145
  log "----"
112
146
  end
113
147
  end
@@ -9,7 +9,10 @@ class TestLogger
9
9
  end
10
10
  end
11
11
 
12
+ ResponseStub = Struct.new(:code, :message, :body)
13
+
12
14
  class TestConnectionLogging < Test::Unit::TestCase
15
+
13
16
  def setup
14
17
  @connection = Network::Connection.new("http://example.com/path")
15
18
  @connection.logger = TestLogger.new
@@ -31,10 +34,11 @@ class TestConnectionLogging < Test::Unit::TestCase
31
34
  end
32
35
 
33
36
  def test_log_response
34
- @connection.send(:log_response, "response data")
37
+ response = ResponseStub.new("200", "OK", "response data")
38
+ @connection.send(:log_response, response, 0.16)
35
39
  log = @connection.logger.log
36
40
 
37
- assert_match /<---/, log
41
+ assert_match /<-- 200 OK \(13 bytes 0.16ms\)/, log
38
42
  assert_match /response data/, log
39
43
  assert_match /----/, log
40
44
  end
@@ -46,13 +50,15 @@ class TestConnectionLogging < Test::Unit::TestCase
46
50
  end
47
51
 
48
52
  def test_response_filtering
53
+ response = ResponseStub.new("200", "OK", "response")
49
54
  @connection.response_filter = Proc.new {|req| "#{req} is filtered"}
50
- @connection.send(:log_response, "response")
55
+ @connection.send(:log_response, response)
51
56
  assert_match /response is filtered/, @connection.logger.log
52
57
  end
53
58
  end
54
59
 
55
60
  class TestConnection < Test::Unit::TestCase
61
+
56
62
  def setup
57
63
  @connection = Network::Connection.new("http://example.com/path")
58
64
  @http = mock('http')
@@ -65,14 +71,37 @@ class TestConnection < Test::Unit::TestCase
65
71
  { :class => Errno::ECONNABORTED, :message => "The remote server reset the connection"},
66
72
  { :class => Errno::ECONNREFUSED, :message => "The connection was refused by the remote server"},
67
73
  ].each do |exception|
68
- Net::HTTP.any_instance.expects(:request).raises exception[:class]
69
74
  e = assert_raise Network::Error do
70
- @connection.post("some data")
75
+ @connection.send(:try_request) do
76
+ raise exception[:class]
77
+ end
71
78
  end
72
79
  assert_equal exception[:message], e.message
73
80
  end
74
81
  end
75
82
 
83
+ def test_post_methods
84
+ sec = sequence('order')
85
+ @connection.expects(:log_request).in_sequence(sec)
86
+ @connection.expects(:http).in_sequence(sec).returns(stub('http', :post => true))
87
+ @connection.expects(:log_response).in_sequence(sec)
88
+ @connection.expects(:handle_response).in_sequence(sec)
89
+
90
+ @connection.post("hello")
91
+ end
92
+
93
+ def test_response_handler_raises_response_error_if_response_code_not_in_200_299
94
+ [300, 400, 500].each do |code|
95
+ assert_raise Network::ResponseError do
96
+ @connection.send(:handle_response, ResponseStub.new(code))
97
+ end
98
+ end
99
+ end
100
+
101
+ def test_response_handler_returns_response_body_if_response_code_200_299
102
+ assert_equal "response", @connection.send(:handle_response, ResponseStub.new(200, "OK", "response"))
103
+ end
104
+
76
105
  def test_default_timeouts
77
106
  assert_equal Network::Connection::READ_TIMEOUT, @connection.read_timeout
78
107
  assert_equal Network::Connection::OPEN_TIMEOUT, @connection.open_timeout
@@ -86,24 +115,21 @@ class TestConnection < Test::Unit::TestCase
86
115
  end
87
116
 
88
117
  def test_default_headers_for_post_request
89
- Net::HTTP.any_instance.expects(:post).with("/path", "data",
90
- { 'Content-Type' => 'application/x-www-form-urlencoded',
91
- 'Content-Length' => '4' })
92
- @connection.post("data")
118
+ expected_headers = { 'Content-Type' => 'application/x-www-form-urlencoded',
119
+ 'Content-Length' => '4' }
120
+
121
+ assert_equal expected_headers, @connection.send(:post_headers, "data")
93
122
  end
94
123
 
95
124
  def test_user_headers_are_not_overwrited_by_default_headers
96
- excepted_headers = {
97
- 'Content-Type' => 'application/xml',
98
- 'Accept' => 'text/plain'
99
- }
125
+ user_headers = { 'Content-Type' => 'application/xml',
126
+ 'Accept' => 'text/plain' }
100
127
 
101
- Net::HTTP.any_instance.expects(:post).with("/path",
102
- "data",
103
- excepted_headers.update('Content-Length' => '4'))
128
+ expected_headers = { 'Content-Length' => '4' }.update(user_headers)
129
+
130
+ @connection.headers = user_headers
104
131
 
105
- @connection.headers = excepted_headers
106
- @connection.post("data")
132
+ assert_equal expected_headers, @connection.send(:post_headers, "data")
107
133
  end
108
134
 
109
135
  def test_configure_ssl_if_scheme_is_https
data/test/test_helper.rb CHANGED
@@ -1,6 +1,5 @@
1
- require "test/unit"
2
- require "rubygems"
3
- require "mocha"
4
- require 'turn'
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'mocha'
5
4
 
6
5
  require 'lib/network'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alovak-network
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pavel Gabriel
@@ -43,7 +43,6 @@ extra_rdoc_files: []
43
43
  files:
44
44
  - lib/network/connection.rb
45
45
  - lib/network.rb
46
- - test/network/test_connection.rb
47
46
  has_rdoc: false
48
47
  homepage: http://github.com/alovak/network/
49
48
  licenses:
@@ -73,4 +72,5 @@ specification_version: 2
73
72
  summary: HTTP/HTTPS communication module based on ruby net/http, net/https modules
74
73
  test_files:
75
74
  - test/network/test_network.rb
75
+ - test/network/test_connection.rb
76
76
  - test/test_helper.rb