sensu-plugins-http-boutetnico 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,232 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: false
3
+
4
+ #
5
+ # check-http-json
6
+ #
7
+ # DESCRIPTION:
8
+ # Takes either a URL or a combination of host/path/query/port/ssl, and checks
9
+ # for valid JSON output in the response. Can also optionally validate simple
10
+ # string key/value pairs, and optionally check if a specified value is within
11
+ # bounds.
12
+ #
13
+ # OUTPUT:
14
+ # plain text
15
+ #
16
+ # PLATFORMS:
17
+ # Linux
18
+ #
19
+ # DEPENDENCIES:
20
+ # gem: sensu-plugin
21
+ # gem: json
22
+ #
23
+ # USAGE:
24
+ # Check that will verify http status and JSON validity
25
+ # ./check-http-json.rb -u http://my.site.com/health.json
26
+ #
27
+ # Check that will verify http status, JSON validity, and that page.totalElements value is
28
+ # greater than 10
29
+ # ./check-http-json.rb -u http://my.site.com/metric.json --key page.totalElements --value-greater-than 10
30
+ #
31
+ # Check that will POST json
32
+ # ./check-http-json.rb -u http://my.site.com/metric.json -m POST --header 'Content-type: application/json' --post-body '{"serverId": "myserver"}'
33
+ #
34
+ # NOTES:
35
+ # Based on Check HTTP by Sonian Inc.
36
+ #
37
+ # LICENSE:
38
+ # Copyright 2013 Matt Revell <nightowlmatt@gmail.com>
39
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
40
+ # for details.
41
+ #
42
+
43
+ require 'sensu-plugin/check/cli'
44
+ require 'json'
45
+ require 'net/http'
46
+ require 'net/https'
47
+
48
+ #
49
+ # Check JSON
50
+ #
51
+ class CheckJson < Sensu::Plugin::Check::CLI
52
+ option :url, short: '-u URL'
53
+ option :host, short: '-h HOST'
54
+ option :path, short: '-p PATH'
55
+ option :query, short: '-q QUERY'
56
+ option :port, short: '-P PORT', proc: proc(&:to_i)
57
+ option :method, short: '-m GET|POST'
58
+ option :postbody, short: '-b /file/with/post/body'
59
+ option :post_body, long: '--post-body VALUE'
60
+ option :header, short: '-H HEADER', long: '--header HEADER'
61
+ option :ssl, short: '-s', boolean: true, default: false
62
+ option :insecure, short: '-k', boolean: true, default: false
63
+ option :user, short: '-U', long: '--username USER'
64
+ option :password, short: '-a', long: '--password PASS'
65
+ option :cert, short: '-c FILE', long: '--cert FILE'
66
+ option :certkey, long: '--cert-key FILE'
67
+ option :cacert, short: '-C FILE', long: '--cacert FILE'
68
+ option :timeout, short: '-t SECS', proc: proc(&:to_i), default: 15
69
+ option :key, short: '-K KEY', long: '--key KEY'
70
+ option :value, short: '-v VALUE', long: '--value VALUE'
71
+ option :valueGt, long: '--value-greater-than VALUE'
72
+ option :valueLt, long: '--value-less-than VALUE'
73
+ option :whole_response, short: '-w', long: '--whole-response', boolean: true, default: false
74
+ option :dump_json, short: '-d', long: '--dump-json', boolean: true, default: false
75
+ option :pretty, long: '--pretty', boolean: true, default: false
76
+
77
+ option :response_code,
78
+ long: '--response-code REGEX',
79
+ description: 'Critical if HTTP response code does not match REGEX',
80
+ default: '^2([0-9]{2})$'
81
+
82
+ def run
83
+ if config[:url]
84
+ uri = URI.parse(config[:url])
85
+ config[:host] = uri.host
86
+ config[:path] = uri.path
87
+ config[:query] = uri.query
88
+ config[:port] = uri.port
89
+ config[:ssl] = uri.scheme == 'https'
90
+ else
91
+ # #YELLOW
92
+ unless config[:host] && config[:path]
93
+ unknown 'No URL specified'
94
+ end
95
+ config[:port] ||= config[:ssl] ? 443 : 80
96
+ end
97
+
98
+ begin
99
+ Timeout.timeout(config[:timeout]) do
100
+ acquire_resource
101
+ end
102
+ rescue Timeout::Error
103
+ critical 'Connection timed out'
104
+ rescue StandardError => e
105
+ critical "Connection error: #{e.message}"
106
+ end
107
+ end
108
+
109
+ def deep_value(data, desired_key, parent = '')
110
+ case data
111
+ when Array
112
+ data.each_with_index do |value, index|
113
+ arr_key = parent + '[' + index.to_s + ']'
114
+
115
+ if arr_key == desired_key
116
+ return value.nil? ? 'null' : value
117
+ end
118
+
119
+ if desired_key.include? arr_key
120
+ search = deep_value(value, desired_key, arr_key)
121
+
122
+ return search unless search.nil?
123
+ end
124
+ end
125
+ when Hash
126
+ data.each do |key, value|
127
+ key_prefix = parent.empty? ? '' : '.'
128
+ hash_key = parent + key_prefix + key
129
+
130
+ if hash_key == desired_key
131
+ return value.nil? ? 'null' : value
132
+ end
133
+
134
+ if desired_key.include?(hash_key + '.') || desired_key.include?(hash_key + '[')
135
+ search = deep_value(value, desired_key, hash_key)
136
+
137
+ return search unless search.nil?
138
+ end
139
+ end
140
+ end
141
+ end
142
+
143
+ def json_valid?(str)
144
+ ::JSON.parse(str)
145
+ true
146
+ rescue ::JSON::ParserError
147
+ false
148
+ end
149
+
150
+ def acquire_resource
151
+ http = Net::HTTP.new(config[:host], config[:port])
152
+
153
+ if config[:ssl]
154
+ http.use_ssl = true
155
+ if config[:cert]
156
+ cert_data = File.read(config[:cert])
157
+ http.cert = OpenSSL::X509::Certificate.new(cert_data)
158
+ if config[:certkey]
159
+ cert_data = File.read(config[:certkey])
160
+ end
161
+ http.key = OpenSSL::PKey::RSA.new(cert_data, nil)
162
+ end
163
+ http.ca_file = config[:cacert] if config[:cacert]
164
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE if config[:insecure]
165
+ end
166
+
167
+ req = if config[:method] == 'POST'
168
+ Net::HTTP::Post.new([config[:path], config[:query]].compact.join('?'))
169
+ else
170
+ Net::HTTP::Get.new([config[:path], config[:query]].compact.join('?'))
171
+ end
172
+ if config[:postbody]
173
+ post_body = IO.readlines(config[:postbody])
174
+ req.body = post_body.join
175
+ end
176
+ if config[:post_body]
177
+ req.body = config[:post_body]
178
+ end
179
+ unless config[:user].nil? && config[:password].nil?
180
+ req.basic_auth config[:user], config[:password]
181
+ end
182
+ if config[:header]
183
+ config[:header].split(',').each do |header|
184
+ h, v = header.split(':', 2)
185
+ req[h] = v.strip
186
+ end
187
+ end
188
+ res = http.request(req)
189
+
190
+ if res.code !~ /#{config[:response_code]}/
191
+ critical "http code: #{res.code}: body: #{res.body}" if config[:whole_response]
192
+ critical res.code
193
+ end
194
+ critical 'invalid JSON from request' unless json_valid?(res.body)
195
+ ok 'valid JSON returned' if config[:key].nil? && config[:value].nil?
196
+
197
+ json = ::JSON.parse(res.body)
198
+
199
+ begin
200
+ leaf = deep_value(json, config[:key])
201
+
202
+ raise "could not find key: #{config[:key]}" if leaf.nil?
203
+
204
+ message = "key has expected value: '#{config[:key]}' "
205
+ if config[:value]
206
+ raise "unexpected value for key: '#{leaf}' != '#{config[:value]}'" unless leaf.to_s == config[:value].to_s
207
+
208
+ message += "equals '#{config[:value]}'"
209
+ end
210
+ if config[:valueGt]
211
+ raise "unexpected value for key: '#{leaf}' not > '#{config[:valueGt]}'" unless leaf.to_f > config[:valueGt].to_f
212
+
213
+ message += "greater than '#{config[:valueGt]}'"
214
+ end
215
+ if config[:valueLt]
216
+ raise "unexpected value for key: '#{leaf}' not < '#{config[:valueLt]}'" unless leaf.to_f < config[:valueLt].to_f
217
+
218
+ message += "less than '#{config[:valueLt]}'"
219
+ end
220
+
221
+ ok message
222
+ rescue StandardError => e
223
+ if config[:dump_json]
224
+ json_response = config[:pretty] ? ::JSON.pretty_generate(json) : json
225
+ message = "key check failed: #{e}. Response: #{json_response}"
226
+ else
227
+ message = "key check failed: #{e}"
228
+ end
229
+ critical message
230
+ end
231
+ end
232
+ end
@@ -0,0 +1,461 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: false
3
+
4
+ #
5
+ # check-http
6
+ #
7
+ # DESCRIPTION:
8
+ # Takes either a URL or a combination of host/path/port/ssl, and checks for
9
+ # a 200 response (that matches a pattern, if given). Can use client certs.
10
+ #
11
+ # OUTPUT:
12
+ # plain text
13
+ #
14
+ # PLATFORMS:
15
+ # Linux
16
+ #
17
+ # DEPENDENCIES:
18
+ # gem: sensu-plugin
19
+ #
20
+ # USAGE:
21
+ # Basic HTTP check - expect a 200 response
22
+ # check-http.rb -u http://my.site.com
23
+ #
24
+ # Pattern check - expect a 200 response and the string 'OK' in the body
25
+ # check-http.rb -u http://my.site.com/health -q 'OK'
26
+ #
27
+ # Check if a response is greater than the specified minimum value
28
+ # check-http.rb -u https://my.site.com/redirect --min-bytes 10
29
+ #
30
+ # Check response code - expect a 301 response
31
+ # check-http.rb -u https://my.site.com/redirect --response-code 301 -r
32
+ #
33
+ # Use a proxy to check a URL
34
+ # check-http.rb -u https://www.google.com --proxy-url http://my.proxy.com:3128
35
+ #
36
+ # Use a proxy with username and password to check a URL
37
+ # NOTE: Use 'check token substition' to avoid credentials leakage!
38
+ # check-http.rb -u https://www.google.com --proxy-url http://a_user:a_pass@my.proxy.com:3128
39
+ #
40
+ # Check something with needing to set multiple headers
41
+ # check-http.rb -u https://www.google.com --header 'Origin: ma.local.box, SomeRandomHeader: foo'
42
+ #
43
+ # Check something that requires a POST with json data
44
+ # check-http.rb -u https://httpbin.org/post --method POST --header 'Content-type: application/json' --body '{"foo": "bar"}'
45
+ # NOTES:
46
+ #
47
+ # LICENSE:
48
+ # Copyright 2011 Sonian, Inc <chefs@sonian.net>
49
+ # Updated by Lewis Preson 2012 to accept basic auth credentials
50
+ # Updated by SweetSpot 2012 to require specified redirect
51
+ # Updated by Chris Armstrong 2013 to accept multiple headers
52
+ # Updated by Mark Clarkson 2018 to accept proxy auth credentials
53
+ # Released under the same terms as Sensu (the MIT license); see LICENSE
54
+ # for details.
55
+ #
56
+
57
+ require 'sensu-plugins-http'
58
+ require 'sensu-plugin/check/cli'
59
+ require 'net/http'
60
+ require 'net/https'
61
+ require 'digest'
62
+ require 'resolv-replace'
63
+
64
+ #
65
+ # Check HTTP
66
+ #
67
+ class CheckHttp < Sensu::Plugin::Check::CLI
68
+ option :ua,
69
+ short: '-x USER-AGENT',
70
+ long: '--user-agent USER-AGENT',
71
+ description: 'Specify a USER-AGENT',
72
+ default: 'Sensu-HTTP-Check'
73
+
74
+ option :url,
75
+ short: '-u URL',
76
+ long: '--url URL',
77
+ description: 'A URL to connect to'
78
+
79
+ option :host,
80
+ short: '-h HOST',
81
+ long: '--hostname HOSTNAME',
82
+ description: 'A HOSTNAME to connect to'
83
+
84
+ option :port,
85
+ short: '-P PORT',
86
+ long: '--port PORT',
87
+ proc: proc(&:to_i),
88
+ description: 'Select another port'
89
+
90
+ option :request_uri,
91
+ short: '-p PATH',
92
+ long: '--request-uri PATH',
93
+ description: 'Specify a uri path'
94
+
95
+ option :method,
96
+ short: '-m GET|HEAD|POST|PUT',
97
+ long: '--method GET|HEAD|POST|PUT',
98
+ description: 'Specify a GET, HEAD, POST, or PUT operation; defaults to GET',
99
+ in: %w[GET HEAD POST PUT],
100
+ default: 'GET'
101
+
102
+ option :header,
103
+ short: '-H HEADER',
104
+ long: '--header HEADER',
105
+ description: 'Send one or more comma-separated headers with the request'
106
+
107
+ option :headerfile,
108
+ long: '--headerfile FILE',
109
+ description: 'Send headers with the request, read from FILE, separated by newline'
110
+
111
+ option :body,
112
+ short: '-d BODY',
113
+ long: '--body BODY',
114
+ description: 'Send a data body string with the request'
115
+
116
+ option :ssl,
117
+ short: '-s',
118
+ boolean: true,
119
+ description: 'Enabling SSL connections',
120
+ default: false
121
+
122
+ option :insecure,
123
+ short: '-k',
124
+ boolean: true,
125
+ description: 'Enabling insecure connections',
126
+ default: false
127
+
128
+ option :user,
129
+ short: '-U',
130
+ long: '--username USER',
131
+ description: 'A username to connect as'
132
+
133
+ option :password,
134
+ short: '-a',
135
+ long: '--password PASS',
136
+ description: 'A password to use for the username'
137
+
138
+ option :cert,
139
+ short: '-c FILE',
140
+ long: '--cert FILE',
141
+ description: 'Cert to use'
142
+
143
+ option :cacert,
144
+ short: '-C FILE',
145
+ long: '--cacert FILE',
146
+ description: 'A CA Cert to use'
147
+
148
+ option :expiry,
149
+ short: '-e EXPIRY',
150
+ long: '--expiry EXPIRY',
151
+ proc: proc(&:to_i),
152
+ description: 'Warn EXPIRE days before cert expires'
153
+
154
+ option :pattern,
155
+ short: '-q PAT',
156
+ long: '--query PAT',
157
+ description: 'Query for a specific pattern that must exist'
158
+
159
+ option :negpattern,
160
+ short: '-n PAT',
161
+ long: '--negquery PAT',
162
+ description: 'Query for a specific pattern that must be absent'
163
+
164
+ option :sha256checksum,
165
+ short: '-S CHECKSUM',
166
+ long: '--checksum CHECKSUM',
167
+ description: 'SHA-256 checksum'
168
+
169
+ option :timeout,
170
+ short: '-t SECS',
171
+ long: '--timeout SECS',
172
+ proc: proc(&:to_i),
173
+ description: 'Set the total execution timeout in seconds',
174
+ default: 15
175
+
176
+ option :open_timeout,
177
+ long: '--open-timeout SECS',
178
+ proc: proc(&:to_i),
179
+ description: 'Number of seconds to wait for the connection to open',
180
+ default: 15
181
+
182
+ option :read_timeout,
183
+ long: '--read-timeout SECS',
184
+ proc: proc(&:to_i),
185
+ description: 'Number of seconds to wait for one block to be read',
186
+ default: 15
187
+
188
+ option :dns_timeout,
189
+ long: '--dns-timeout SECS',
190
+ proc: proc(&:to_f),
191
+ description: 'Number of seconds to allow for DNS resolution. Accepts decimal number.',
192
+ default: 0.8
193
+
194
+ option :redirectok,
195
+ short: '-r',
196
+ boolean: true,
197
+ description: 'Check if a redirect is ok',
198
+ default: false
199
+
200
+ option :redirectto,
201
+ short: '-R URL',
202
+ long: '--redirect-to URL',
203
+ description: 'Redirect to another page'
204
+
205
+ option :whole_response,
206
+ short: '-w',
207
+ long: '--whole-response',
208
+ boolean: true,
209
+ default: false,
210
+ description: 'Print whole output when check fails'
211
+
212
+ option :response_bytes,
213
+ short: '-b BYTES',
214
+ long: '--response-bytes BYTES',
215
+ description: 'Print BYTES of the output',
216
+ proc: proc(&:to_i)
217
+
218
+ option :require_bytes,
219
+ short: '-B BYTES',
220
+ long: '--require-bytes BYTES',
221
+ description: 'Check the response contains exactly BYTES bytes',
222
+ proc: proc(&:to_i)
223
+
224
+ option :min_bytes,
225
+ short: '-g BYTES',
226
+ long: '--min-bytes BYTES',
227
+ description: 'Check the response contains at least BYTES bytes',
228
+ proc: proc(&:to_i)
229
+
230
+ option :response_code,
231
+ long: '--response-code REGEX',
232
+ description: 'Critical if HTTP response code does not match REGEX'
233
+
234
+ option :proxy_url,
235
+ long: '--proxy-url PROXY_URL',
236
+ description: 'Use a proxy server to connect'
237
+
238
+ option :no_proxy,
239
+ long: '--noproxy',
240
+ boolean: true,
241
+ description: 'Do not use proxy server even from environment http_proxy setting',
242
+ default: false
243
+
244
+ option :aws_v4,
245
+ long: '--aws-v4',
246
+ boolean: true,
247
+ description: 'Sign http request with AWS v4 signature',
248
+ default: false
249
+
250
+ option :aws_v4_region,
251
+ long: '--aws-v4-region REGION',
252
+ description: 'Region to use for AWS v4 signing. Defaults to AWS_REGION or AWS_DEFAULT_REGION'
253
+
254
+ option :aws_v4_service,
255
+ long: '--aws-v4-service SERVICE',
256
+ description: 'Service name to use when building the v4 signature',
257
+ default: 'execute-api'
258
+
259
+ include SensuPluginsHttp::AwsV4
260
+
261
+ def run
262
+ if config[:url]
263
+ uri = URI.parse(config[:url])
264
+ config[:host] = uri.host
265
+ config[:port] = uri.port
266
+ config[:request_uri] = uri.request_uri
267
+ config[:ssl] = uri.scheme == 'https'
268
+ else
269
+ # #YELLOW
270
+ unless config[:host] && config[:request_uri]
271
+ unknown 'No URL specified'
272
+ end
273
+ config[:port] ||= config[:ssl] ? 443 : 80
274
+ end
275
+
276
+ # Use Ruby DNS Resolver and set DNS resolution timeout to dns_timeout value
277
+ hosts_resolver = Resolv::Hosts.new
278
+ dns_resolver = Resolv::DNS.new
279
+ dns_resolver.timeouts = config[:dns_timeout]
280
+ Resolv::DefaultResolver.replace_resolvers([hosts_resolver, dns_resolver])
281
+
282
+ begin
283
+ Timeout.timeout(config[:timeout]) do
284
+ acquire_resource
285
+ end
286
+ rescue Net::OpenTimeout
287
+ critical 'Request timed out opening connection'
288
+ rescue Net::ReadTimeout
289
+ critical 'Request timed out reading data'
290
+ rescue Timeout::Error
291
+ critical 'Request timed out'
292
+ rescue StandardError => e
293
+ critical "Request error: #{e.message}"
294
+ end
295
+ end
296
+
297
+ def acquire_resource
298
+ http = nil
299
+
300
+ if config[:no_proxy]
301
+ http = Net::HTTP.new(config[:host], config[:port], nil, nil)
302
+ elsif config[:proxy_url]
303
+ proxy_uri = URI.parse(config[:proxy_url])
304
+ if proxy_uri.host.nil?
305
+ unknown 'Invalid proxy url specified'
306
+ end
307
+ http = if proxy_uri.user && proxy_uri.password
308
+ Net::HTTP.new(config[:host], config[:port], proxy_uri.host, proxy_uri.port, proxy_uri.user, proxy_uri.password)
309
+ else
310
+ Net::HTTP.new(config[:host], config[:port], proxy_uri.host, proxy_uri.port)
311
+ end
312
+ else
313
+ http = Net::HTTP.new(config[:host], config[:port])
314
+ end
315
+ http.read_timeout = config[:read_timeout]
316
+ http.open_timeout = config[:open_timeout]
317
+ http.ssl_timeout = config[:timeout]
318
+ http.continue_timeout = config[:timeout]
319
+ http.keep_alive_timeout = config[:timeout]
320
+
321
+ warn_cert_expire = nil
322
+ if config[:ssl]
323
+ http.use_ssl = true
324
+ if config[:cert]
325
+ cert_data = File.read(config[:cert])
326
+ http.cert = OpenSSL::X509::Certificate.new(cert_data)
327
+ http.key = OpenSSL::PKey::RSA.new(cert_data, nil)
328
+ end
329
+ http.ca_file = config[:cacert] if config[:cacert]
330
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE if config[:insecure]
331
+
332
+ unless config[:expiry].nil?
333
+ expire_warn_date = Time.now + (config[:expiry] * 60 * 60 * 24)
334
+ # We can't raise inside the callback, have to check when we finish.
335
+ http.verify_callback = proc do |preverify_ok, ssl_context|
336
+ if ssl_context.current_cert.not_after <= expire_warn_date
337
+ warn_cert_expire = ssl_context.current_cert.not_after
338
+ end
339
+
340
+ preverify_ok
341
+ end
342
+ end
343
+ end
344
+
345
+ req = case config[:method]
346
+ when 'GET'
347
+ Net::HTTP::Get.new(config[:request_uri], 'User-Agent' => config[:ua])
348
+ when 'HEAD'
349
+ Net::HTTP::Head.new(config[:request_uri], 'User-Agent' => config[:ua])
350
+ when 'POST'
351
+ Net::HTTP::Post.new(config[:request_uri], 'User-Agent' => config[:ua])
352
+ when 'PUT'
353
+ Net::HTTP::Put.new(config[:request_uri], 'User-Agent' => config[:ua])
354
+ end
355
+
356
+ unless config[:user].nil? && config[:password].nil?
357
+ req.basic_auth config[:user], config[:password]
358
+ end
359
+ if config[:header]
360
+ config[:header].split(',').each do |header|
361
+ h, v = header.split(':', 2)
362
+ req[h.strip] = v.strip
363
+ end
364
+ end
365
+
366
+ if config[:headerfile]
367
+ File.readlines(config[:headerfile]).each do |line|
368
+ h, v = line.split(':', 2)
369
+ req[h.strip] = v.strip
370
+ end
371
+ end
372
+
373
+ req.body = config[:body] if config[:body]
374
+
375
+ req = apply_v4_signature(http, req, config) if config[:aws_v4]
376
+
377
+ res = http.request(req)
378
+
379
+ body = if config[:whole_response]
380
+ "\n" + res.body.to_s
381
+ else
382
+ body = if config[:response_bytes] # rubocop:disable Lint/UselessAssignment
383
+ "\n" + res.body[0..config[:response_bytes]]
384
+ else
385
+ ''
386
+ end
387
+ end
388
+
389
+ if config[:require_bytes] && res.body.length != config[:require_bytes]
390
+ critical "Response was #{res.body.length} bytes instead of #{config[:require_bytes]}" + body
391
+ end
392
+
393
+ if config[:min_bytes] && res.body.length < config[:min_bytes]
394
+ critical "Response was #{res.body.length} bytes instead of the indicated minimum #{config[:min_bytes]}" + body
395
+ end
396
+
397
+ unless warn_cert_expire.nil?
398
+ warning "Certificate will expire #{warn_cert_expire}"
399
+ end
400
+
401
+ size = res.body.nil? ? '0' : res.body.size
402
+
403
+ handle_response(res, size, body)
404
+ end
405
+
406
+ def handle_response(res, size, body)
407
+ case res.code
408
+ when /^2/
409
+ if config[:redirectto]
410
+ critical "Expected redirect to #{config[:redirectto]} but got #{res.code}" + body
411
+ elsif config[:pattern]
412
+ if res.body =~ /#{config[:pattern]}/
413
+ ok "#{res.code}, found /#{config[:pattern]}/ in #{size} bytes" + body
414
+ else
415
+ critical "#{res.code}, did not find /#{config[:pattern]}/ in #{size} bytes: #{res.body[0...200]}..."
416
+ end
417
+ elsif config[:negpattern]
418
+ if res.body =~ /#{config[:negpattern]}/
419
+ critical "#{res.code}, found /#{config[:negpattern]}/ in #{size} bytes: #{res.body[0...200]}..."
420
+ else
421
+ ok "#{res.code}, did not find /#{config[:negpattern]}/ in #{size} bytes" + body
422
+ end
423
+ elsif config[:sha256checksum]
424
+ if Digest::SHA256.hexdigest(res.body).eql? config[:sha256checksum]
425
+ ok "#{res.code}, checksum match #{config[:sha256checksum]} in #{size} bytes" + body
426
+ else
427
+ critical "#{res.code}, checksum did not match #{config[:sha256checksum]} in #{size} bytes: #{res.body[0...200]}..."
428
+ end
429
+ else
430
+ ok("#{res.code}, #{size} bytes" + body) unless config[:response_code]
431
+ end
432
+ when /^3/
433
+ if config[:redirectok] || config[:redirectto]
434
+ if config[:redirectok]
435
+ # #YELLOW
436
+ ok("#{res.code}, #{size} bytes" + body) unless config[:response_code] # rubocop:disable Metrics/BlockNesting
437
+ elsif config[:redirectto]
438
+ # #YELLOW
439
+ if config[:redirectto] == res['Location'] # rubocop:disable Metrics/BlockNesting
440
+ ok "#{res.code} found redirect to #{res['Location']}" + body
441
+ else
442
+ critical "Expected redirect to #{config[:redirectto]} instead redirected to #{res['Location']}" + body
443
+ end
444
+ end
445
+ else
446
+ warning res.code + body
447
+ end
448
+ when /^4/, /^5/
449
+ critical(res.code + body) unless config[:response_code]
450
+ else
451
+ warning(res.code + body) unless config[:response_code]
452
+ end
453
+
454
+ if config[:response_code] && res.code =~ /#{config[:response_code]}/
455
+ ok "#{res.code}, #{size} bytes" + body
456
+
457
+ else
458
+ critical res.code + body
459
+ end
460
+ end
461
+ end