net-ping 1.1.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES CHANGED
@@ -1,3 +1,26 @@
1
+ == 1.2.0 - 5-Dec-2006
2
+ * Internal reorganization - each class now lives in its own file.
3
+ * Added the Ping::ICMP class. Thanks go to Jos Backus for contributing a
4
+ large part of the code.
5
+ * The host argument is now optional in the constructor. You can now specify
6
+ it in the ping method instead. Note that it must be specified in one place
7
+ or the other.
8
+ * Each PingXXX class is now Ping::XXX instead. However, class name aliases
9
+ have been setup for backwards compatibility for now.
10
+ * The constructor for each Ping types now yields self.
11
+ * Added the pingecho alias for the ping method for each Ping type.
12
+ * Added the Ping::HTTP#follow_redirect accessor.
13
+ * The Ping::HTTP#ping method now honors the timeout value.
14
+ * The Ping::HTTP class now follows redirects automatically, though this is
15
+ configurable with the follow_redirect accessor.
16
+ * The Ping::TCP.ecr and Ping::TCP.ecr= methods are now true class method
17
+ aliases (they were just wrappers previously).
18
+ * The Ping::UDP class now enforces a 64 character limit on data that can be
19
+ sent on a udp ping.
20
+ * Updated the gemspec. Specifically, MS Windows now has a dependency on
21
+ the win32-open3 package.
22
+ * Added inline rdoc.
23
+
1
24
  == 1.1.1 - 15-Jun-2006
2
25
  * Fixed a bug in PingTCP (bad variable name). Thanks go to Anoop Chandran
3
26
  for the spot.
data/MANIFEST CHANGED
@@ -3,15 +3,23 @@ CHANGES
3
3
  README
4
4
  test.rb
5
5
  install.rb
6
+ net-ping.gemspec
6
7
 
7
8
  examples/test_pingexternal.rb
8
9
  examples/test_pinghttp.rb
9
10
  examples/test_pingtcp.rb
10
11
  examples/test_pingudp.rb
11
12
 
12
- net/pingsimple.rb
13
+ lib/net/ping.rb
14
+ lib/net/ping/icmp.rb
15
+ lib/net/ping/tcp.rb
16
+ lib/net/ping/udp.rb
17
+ lib/net/ping/http.rb
18
+ lib/net/ping/external.rb
13
19
 
14
20
  test/tc_pingexternal.rb
21
+ test/tc_pinghttp.rb
22
+ test/tc_pingicmp.rb
15
23
  test/tc_pingtcp.rb
16
24
  test/tc_pingudp.rb
17
- test/tc_pinghttp.rb
25
+ test/ts_ping.rb
data/README CHANGED
@@ -3,7 +3,8 @@
3
3
 
4
4
  == Prerequisites
5
5
  * Ruby 1.8.0 or later
6
- * The win32/open3 package is required for Win32 systems.
6
+ * The win32/open3 package is required for Win32 systems when using the
7
+ Net::Ping::External class.
7
8
 
8
9
  == Installation
9
10
  === Manual Installation
@@ -18,3 +19,17 @@
18
19
  pertaining to ECONNREFUSED with regards to TCP pings.
19
20
 
20
21
  Also note the documentation regarding down hosts.
22
+
23
+ == How to require net-ping
24
+ You can do either this:
25
+
26
+ require 'net/ping'
27
+
28
+ In which case you will get Net::Ping and all of its subclasses. Or,
29
+ you can load individual subclasses like this:
30
+
31
+ require 'net/ping/tcp'
32
+
33
+ The former has the advantage of being easier to remember and all inclusive,
34
+ not to mention backwards compatible. The latter has the advantage of
35
+ reducing your memory footprint.
data/doc/ping.txt CHANGED
@@ -1,16 +1,16 @@
1
- == Description
1
+ = Description
2
2
  A simple Ruby interface to the 'ping' command.
3
3
 
4
- == Synopsis
4
+ = Synopsis
5
5
  require "net/ping"
6
6
  include Net
7
7
 
8
- PingTCP.econnrefused = true
8
+ Ping::TCP.econnrefused = true
9
9
 
10
- pt = Net::PingTCP.new(host)
11
- pu = Net::PingUDP.new(host)
12
- pe = Net::PingExternal.new(host)
13
- ph = Net::PingHTTP.new(uri)
10
+ pt = Net::Ping::TCP.new(host)
11
+ pu = Net::Ping::UDP.new(host)
12
+ pe = Net::Ping::External.new(host)
13
+ ph = Net::Ping::HTTP.new(uri)
14
14
 
15
15
  if pt.ping
16
16
  puts "TCP ping successful"
@@ -36,109 +36,125 @@
36
36
  puts "HTTP ping unsuccessful: " + ph.exception
37
37
  end
38
38
 
39
- == Ping Classes
40
- * PingTCP
41
- * PingUDP
42
- * PingExternal
43
- * PingHTTP
39
+ = Ping Classes
40
+ * Ping::TCP
41
+ * Ping::UDP
42
+ * Ping::External
43
+ * Ping::HTTP
44
+ * Ping::ICMP
44
45
 
45
46
  All Ping classes are children of the Ping parent class (which should
46
47
  never be instantiated directly).
47
48
 
48
- === PingTCP
49
- PingTCP.new(host, port=7, timeout=5)
50
- Creates and returns a new PingTCP object.
49
+ The Ping::ICMP class requires root privileges on UNIX systems.
50
+
51
+ == Net::Ping
52
+ Net::Ping.new(host=nil, port=7, timeout=5)
53
+ Creates and returns a new Ping object. If the host is not specified
54
+ in the constructor then it must be specified in the ping method.
55
+
56
+ == Net::Ping::TCP
57
+ Ping::TCP.econnrefused
58
+ Returns the setting for how ECONNREFUSED is handled. By default, this is
59
+ set to false, i.e. an ECONNREFUSED error is considered a failed ping.
60
+
61
+ Ping::TCP.econnrefused=(bool)
62
+ Sets the behavior for how ECONNREFUSED is handled. By default, this is
63
+ set to false, i.e. an ECONNREFUSED error is considered a failed ping.
64
+
65
+ Ping::TCP#ping(host=nil)
66
+ Attempts to open a connection using TCPSocket with a +host+ specified
67
+ either here or in the constructor. A successful open means the ping was
68
+ successful and true is returned. Otherwise, false is returned.
69
+
70
+ == Net::Ping::UDP
71
+ Ping::UDP#ping
72
+ Attempts to open a connection using UDPSocket and sends the value of
73
+ Ping::UDP#data as a string across the socket. If the return string matches,
74
+ then the ping was successful and true is returned. Otherwise, false is
75
+ returned.
51
76
 
52
- PingTCP.econnrefused
53
- Returns the setting for how ECONNREFUSED is handled. By default, this is
54
- set to false, i.e. an ECONNREFUSED error is considered a failed ping.
77
+ Ping::UDP#data
78
+ Returns the string that is sent across the UDP socket.
55
79
 
56
- PingTCP.econnrefused=(bool)
57
- Sets the behavior for how ECONNREFUSED is handled. By default, this is
58
- set to false, i.e. an ECONNREFUSED error is considered a failed ping.
59
-
60
- PingTCP#ping
61
- PingTCP#ping?
62
- Attempts to open a connection using TCPSocket. A successful open means
63
- the ping was successful and true is returned. Otherwise, false is returned.
64
-
65
- === PingUDP
66
- PingUDP.new(host, port=7, timeout=5)
67
- Creates and returns a new PingUDP object.
68
-
69
- PingUDP#ping
70
- PingUDP#ping?
71
- Attempts to open a connection using UDPSocket and sends the value of
72
- PingUDP#data as a string across the socket. If the return string matches,
73
- then the ping was successful and true is returned. Otherwise, false is
74
- returned.
75
-
76
- PingUDP#data
77
- Returns the string that is sent across the UDP socket.
78
-
79
- PingUDP#data=(string)
80
- Sets the string that is sent across the UDP socket. The default is "ping"
80
+ Ping::UDP#data=(string)
81
+ Sets the string that is sent across the UDP socket. The default is "ping".
82
+ Note that the +string+ cannot be larger than MAX_DATA (64 characters).
81
83
 
82
- === PingExternal
83
- PingExternal.new(host, port=7, timeout=5)
84
- Creates and returns a new PingExternal object.
85
-
86
- PingExternal#ping
87
- PingExternal#ping?
88
- Uses the 'open3' module and calls your system's local 'ping' command with
89
- various options, depending on platform. If nothing is sent to stderr, the
90
- ping was successful and true is returned. Otherwise, false is returned.
91
-
92
- === PingHTTP
93
- PingHTTP.new(uri, port=80, timeout=5)
94
- Creates and returns a new PingHTTP object.
84
+ == Net::Ping::External
85
+ Ping::External#ping
86
+ Uses the 'open3' module and calls your system's local 'ping' command with
87
+ various options, depending on platform. If nothing is sent to stderr, the
88
+ ping was successful and true is returned. Otherwise, false is returned.
89
+
90
+ The MS Windows platform requires the 'win32-open3' package.
95
91
 
96
- PingHTTP#ping
97
- PingHTTP#ping?
98
- Checks for a response against +uri+. As long as a Net::HTTPSuccess or
99
- Net::HTTPOK response is returned, the ping is successful and true is
100
- returned. Otherwise, false is returned and PingHTTP#exception is set to
101
- the error message.
92
+ == Ping::HTTP
93
+ Ping::HTTP.new(uri=nil, port=80, timeout=5)
94
+ Identical to Net::Ping.new except that, instead of a host, the first
95
+ argument is a URI.
102
96
 
103
- PingHTTP#uri
104
- An alias for PingHTTP#host.
97
+ Ping::HTTP#ping
98
+ Checks for a response against +uri+. As long as kind of Net::HTTPSuccess
99
+ response is returned, the ping is successful and true is returned.
100
+ Otherwise, false is returned and Ping::HTTP#exception is set to the error
101
+ message.
102
+
103
+ Note that redirects are automatically followed unless the
104
+ Ping::HTTP#follow_redirects method is set to false.
105
+
106
+ Ping::HTTP#follow_redirect
107
+ Indicates whether or not a redirect should be followed in a ping attempt.
108
+ By default this is set to true.
109
+
110
+ Ping::HTTP#follow_redirect=(bool)
111
+ Sets whether or not a redirect should be followed in a ping attempt. If
112
+ set to false, then any redirect is considered a failed ping.
113
+
114
+ Ping::HTTP#uri
115
+ An alias for Ping::HTTP#host.
105
116
 
106
- PingHTTP#uri=(uri)
107
- An alias for PingHTTP#host=.
117
+ Ping::HTTP#uri=(uri)
118
+ An alias for Ping::HTTP#host=.
119
+
120
+ == Ping::ICMP
121
+ Ping::ICMP#duration
122
+ The time it took to ping the host. Not a precise value but a good estimate.
108
123
 
109
- == Instance Methods
124
+ = Common Instance Methods
110
125
  Ping#exception
111
- Returns the error string that was set if a ping call failed. If an exception
112
- is raised, it is caught and stored in this attribute. It is not raised in
113
- your code.
126
+ Returns the error string that was set if a ping call failed. If an exception
127
+ is raised, it is caught and stored in this attribute. It is not raised in
128
+ your code.
114
129
 
115
- This should be nil if the ping succeeded.
130
+ This should be nil if the ping succeeded.
116
131
 
117
132
  Ping#host
118
- Returns the host name that ping attempts will ping against.
133
+ Returns the host name that ping attempts will ping against.
119
134
 
120
135
  Ping#host=(hostname)
121
- Sets the host name that ping attempts will ping against.
136
+ Sets the host name that ping attempts will ping against.
122
137
 
123
138
  Ping#port
124
- Returns the port number that ping attempts will use.
139
+ Returns the port number that ping attempts will use.
125
140
 
126
141
  Ping#port=(port)
127
- Set the port number to open socket connections on. The default is 7 (or
128
- whatever your 'echo' port is set to). Note that you can also specify a
129
- string, such as "http".
142
+ Set the port number to open socket connections on. The default is 7 (or
143
+ whatever your 'echo' port is set to). Note that you can also specify a
144
+ string, such as "http".
130
145
 
131
146
  Ping#timeout
132
- Returns the amount of time before the timeout module raises a TimeoutError
133
- during connection attempts. The default is 5 seconds.
147
+ Returns the amount of time before the timeout module raises a TimeoutError
148
+ during connection attempts. The default is 5 seconds.
134
149
 
135
150
  Ping#timeout=(time)
136
- Sets the amount of time before the timeout module raises a TimeoutError.
137
- during connection attempts.
151
+ Sets the amount of time before the timeout module raises a TimeoutError.
152
+ during connection attempts.
138
153
 
139
154
  Ping#warning
140
- Returns a warning string that was returned during the ping attempt. This
141
- typically occurs only in the PingExternal class.
155
+ Returns a warning string that was returned during the ping attempt. This
156
+ typically occurs only in the Ping::External class, or the Ping::HTTP class
157
+ if a redirect occurred.
142
158
 
143
159
  == Notes
144
160
  If a host is down *IT IS CONSIDERED A FAILED PING*, and the 'no answer from
@@ -146,7 +162,7 @@ Ping#warning
146
162
  this behavior, in which case you need merely check the exception attribute
147
163
  against a regex as a simple workaround.
148
164
 
149
- == FAQ
165
+ == Pre-emptive FAQ
150
166
  Q: "Why don't you return exceptions if a connection fails?"
151
167
 
152
168
  A: Because ping is only meant to return one of two things - success or
@@ -158,7 +174,7 @@ Ping#warning
158
174
 
159
175
  A: It's possible that the echo port has been disabled on the remote
160
176
  host for security reasons. Your best best is to specify a different port
161
- or to use PingExternal instead.
177
+ or to use Ping::ICMP or Ping::External instead.
162
178
 
163
179
  Q: "Why does TCP ping return false when I know it should return true?"
164
180
 
@@ -177,29 +193,33 @@ Ping#warning
177
193
  A: I *could* but I won't so don't bug me about it. It's far more effort than
178
194
  it's worth.
179
195
 
180
- == Known Bugs
196
+ = Known Bugs
181
197
  You may see a test failure from the tc_pingtcp test case. You can ignore
182
198
  this.
183
199
 
184
200
  Please report any bugs on the project page at
185
201
  http://www.rubyforge.org/projects/shards.
186
202
 
187
- == Future Plans
188
- Add an PingICMP class (help wanted)
189
- (Though see arton's icmpping package on the RAA)
203
+ = Acknowledgements
204
+ The Ping::ICMP#ping method is based largely on the identical method from
205
+ the Net::Ping Perl module by Rob Brown. Much of the code was ported by
206
+ Jos Backus on ruby-talk.
207
+
208
+ = Future Plans
209
+ Add a bind method.
190
210
 
191
- == License
211
+ = License
192
212
  Ruby's
193
213
 
194
- == Copyright
195
- (C) 2003-2005 Daniel J. Berger, All Rights Reserved
214
+ = Copyright
215
+ (C) 2003-2006 Daniel J. Berger, All Rights Reserved
196
216
 
197
- == Warranty
217
+ = Warranty
198
218
  This package is provided "as is" and without any express or
199
219
  implied warranties, including, without limitation, the implied
200
220
  warranties of merchantability and fitness for a particular purpose.
201
221
 
202
- == Author
222
+ = Author
203
223
  Daniel J. Berger
204
224
  djberg96 at gmail dot com
205
225
  imperator on IRC (irc.freenode.net)
data/lib/net/ping.rb CHANGED
@@ -1,237 +1,11 @@
1
- require "socket"
2
- require "timeout"
3
-
4
- module Net
5
- # An abstract base class. Do not instantiate directly.
6
- class Ping
7
- VERSION = "1.1.1"
8
- attr_accessor :host, :port, :timeout
9
- attr_reader :exception, :warning
10
-
11
- def initialize(host, port=nil, timeout=5)
12
- @host = host
13
- @port = port || Socket.getservbyname("echo") || 7
14
- @timeout = timeout
15
- @data = "ping"
16
- @exception = nil
17
- @warning = nil
18
- end
19
-
20
- def ping
21
- @exception = nil
22
- @warning = nil
23
- end
24
- end
25
-
26
- ##########################################################################
27
- # With a TCP ping, simply try to open a connection. If we are successful,
28
- # assume success. In either case, close the connection to be polite.
29
- ##########################################################################
30
- class PingTCP < Ping
31
- @@econnrefused = false
32
-
33
- # Returns whether or not ECONNREFUSED error is to be considered a
34
- # successful ping. The default is false.
35
- def self.econnrefused
36
- @@econnrefused
37
- end
38
-
39
- # An alias for PingTCP.econnrefused
40
- def self.ecr
41
- self.econnrefused
42
- end
43
-
44
- # Sets whether or not an ECONNREFUSED error should be considered a
45
- # successful ping.
46
- def self.econnrefused=(bool)
47
- unless bool.kind_of?(TrueClass) || bool.kind_of?(FalseClass)
48
- raise ArgumentError, "argument must be true or false"
49
- end
50
- @@econnrefused = bool
51
- end
52
-
53
- # An alias for PingTCP.econnrefused=
54
- def self.ecr=(bool)
55
- self.econnrefused = bool
56
- end
57
-
58
- # This method attempts to ping a host and port using a TCPSocket with
59
- # the host and port values passed to the constructor.
60
- def ping
61
- super
62
- success = false
63
- tcp = nil
64
- begin
65
- Timeout.timeout(@timeout){
66
- begin
67
- tcp = TCPSocket.new(@host,@port)
68
- rescue Errno::ECONNREFUSED => err
69
- if @@econnrefused == true
70
- success = true
71
- else
72
- @exception = err
73
- end
74
- rescue Exception => err
75
- @exception = err
76
- else
77
- success = true
78
- end
79
- }
80
- rescue Timeout::Error => err
81
- @exception = err
82
- ensure
83
- tcp.close if tcp
84
- end
85
- success
86
- end
87
-
88
- alias ping? ping
89
- end
90
-
91
- ##########################################################################
92
- # With a UDP ping, send a simple text string and check the return string.
93
- # If they match, assume success.
94
- ##########################################################################
95
- class PingUDP < Ping
96
- attr_accessor :data
97
-
98
- # Sends a simple text string and checks the return string. If they
99
- # match, the ping was successful.
100
- def ping
101
- super
102
- success = false
103
- udp = UDPSocket.open
104
- a = []
105
- begin
106
- Timeout.timeout(@timeout){
107
- udp.connect(@host, @port)
108
- udp.send(@data, 0)
109
- a = udp.recvfrom(64)
110
- }
111
- rescue Exception => err
112
- @exception = err
113
- else
114
- if a[0] == @data
115
- success = true
116
- end
117
- ensure
118
- udp.close if udp
119
- end
120
- success
121
- end
122
-
123
- alias ping? ping
124
- end
125
-
126
- ##################################
127
- # Use your system's ping command
128
- ##################################
129
- class PingExternal < Ping
130
-
131
- # Pings the host using your system's ping utility and checks for any
132
- # errors or warnings.
133
- def ping
134
- super
135
- input, output, error = ""
136
- pstring = "ping "
137
- success = false
138
-
139
- case PLATFORM
140
- when /linux|bsd/i
141
- pstring += "-c 1 #{@host}"
142
- when /solaris|sunos/i
143
- pstring += "#{@host} 1"
144
- when /hpux/i
145
- pstring += "#{@host} -n 1"
146
- when /win32|windows/i
147
- pstring += "-n 1 #{@host}"
148
- else
149
- pstring += "#{@host}"
150
- end
151
-
152
- if File::ALT_SEPARATOR
153
- require "win32/open3"
154
- else
155
- require "open3"
156
- end
157
-
158
- Timeout.timeout(@timeout){
159
- input, output, error = Open3.popen3(pstring)
160
- }
161
-
162
- e = error.gets # Can't chomp yet, might be nil
163
-
164
- input.close
165
- error.close
166
-
167
- unless e.nil?
168
- if e =~ /warning/i
169
- @warning = e.chomp
170
- success = true
171
- else
172
- @exception = e.chomp
173
- end
174
- # The "no answer" response goes to stdout, not stderr, so check it
175
- else
176
- lines = output.readlines
177
- output.close
178
- if lines.nil? || lines.empty?
179
- success = true
180
- else
181
- regexp = /no answer|host unreachable|could not find host/i
182
- lines.each{ |e|
183
- if regexp.match(e)
184
- @exception = e.chomp
185
- end
186
- }
187
- success = true
188
- end
189
- end
190
- success
191
- end
192
-
193
- alias ping? ping
194
- end
195
-
196
- # For this class, +host+ is actually a URI.
197
- class PingHTTP < Ping
198
- require "net/http"
199
- require "uri"
200
- include Net
201
-
202
- # Creates and returns a new PingHTTP object.
203
- #--
204
- # Defined separately in order to set the default port to 80.
205
- def initialize(host, port=80, timeout=5)
206
- super(host, port, timeout)
207
- end
208
-
209
- # Looks for an HTTP response from the URI passed to the constructor.
210
- # If the result is HTTPSuccess or HTTPOK, the ping was successful.
211
- def ping
212
- super
213
- success = false
214
- uri = URI.parse(@host)
215
-
216
- begin
217
- resp = HTTP.get_response(uri.host, uri.path, @port)
218
- rescue Exception => err
219
- @exception = err
220
- else
221
- case resp
222
- when Net::HTTPSuccess, Net::HTTPOK
223
- success = true
224
- else
225
- @exception = resp.message
226
- end
227
- end
228
-
229
- success
230
- end
231
-
232
- alias ping? ping
233
- alias uri host
234
- alias uri= host=
235
- end
236
-
237
- end # Net
1
+ # By doing a "require 'net/ping'" you are requiring every subclass. If you
2
+ # want to require a specific ping type only, do "require 'net/ping/tcp'",
3
+ # for example.
4
+ #
5
+ $LOAD_PATH.unshift File.dirname(__FILE__)
6
+
7
+ require 'ping/tcp'
8
+ require 'ping/udp'
9
+ require 'ping/icmp'
10
+ require 'ping/external'
11
+ require 'ping/http'