- ``byteslimit``: Limit the maximum download size to ``byteslimit`` bytes (default 0 meaning no limit).
- ``minimumFailures``: The number of unsuccessful checks in a row required to mark the address as down. Defaults to 1 if not specified, i.e. report as down on the first unsuccessful check.
- ``failOnIncompleteCheck``: if set to ``true``, return SERVFAIL instead of applying ``backupSelector``, if none of the addresses have completed their background health check yet.
+ - ``headers``: A table of HTTP headers to be added to the request. Any ``_`` in the header name will be replaced with a ``-``.
An example of a list of address sets:
ifurlup("https://example.com/", { {"192.0.2.20", "203.0.113.4"}, {"203.0.113.2"} })
+ An example usage of headers:
+
+ .. code-block:: lua
+
+ ifurlup("https://example.com/", { {"192.0.2.20", "203.0.113.4"}, {"203.0.113.2"} }, { headers={X_API_Key="example-key", Cache_Control="no-cache"} })
+
.. function:: ifurlextup(groups-of-address-url-pairs[, options])
Very similar to ``ifurlup``, but the returned IPs are decoupled from their external health check URLs.
int http_code = pdns::checked_stoi<int>(cd.getOption<string>("httpcode", "200"));
MiniCurl minicurl(useragent, false);
+
+ MiniCurl::MiniCurlHeaders mch;
+ for (auto const & header:cd.getOption<LuaAssociativeTable<string>>("headers", {})) {
+ auto headername = header.first;
+ std::replace(headername.begin(), headername.end(), '_', '-');
+ mch.emplace(headername, header.second);
+ }
string content;
const ComboAddress* rem = nullptr;
if (cd.opts.count("source")) {
ComboAddress src{cd.getOption<string>("source")};
- content=minicurl.getURL(cd.url, rem, &src, timeout, nullptr, false, false, byteslimit, http_code);
+ content=minicurl.getURL(cd.url, rem, &src, timeout, &mch, false, false, byteslimit, http_code);
}
else {
- content=minicurl.getURL(cd.url, rem, nullptr, timeout, nullptr, false, false, byteslimit, http_code);
+ content=minicurl.getURL(cd.url, rem, nullptr, timeout, &mch, false, false, byteslimit, http_code);
}
if (cd.opts.count("stringmatch") && content.find(cd.getOption<string>("stringmatch")) == string::npos) {
throw std::runtime_error(boost::str(boost::format("unable to match content with `%s`") % cd.getOption<string>("stringmatch")));
#!/usr/bin/env python
import unittest
import threading
-import dns
+import dns.rrset
+import dns.rcode
+import dns.rdataclass
+import dns.message
import time
import clientsubnetoption
self.wfile.write(bytes('this page does not exist', 'utf-8'))
return
+ if self.path == "/check-headers":
+ if self.headers.get("my-header", "") != "myvalue":
+ self._set_headers(400)
+ self.wfile.write(bytes('Wrong Header value!', 'utf-8'))
+ return
+
self._set_headers()
if self.path == '/ping.json':
self.wfile.write(bytes('{"ping":"pong"}', 'utf-8'))
ifurlextup IN LUA A "ifurlextup({{{{['192.168.0.1']='http://{prefix}.101:8080/404',['192.168.0.2']='http://{prefix}.102:8080/404'}}, {{['192.168.0.3']='http://{prefix}.101:8080/'}}}})"
+goodheaders.ifurlup IN LUA A ("ifurlup('http://example.com:8080/check-headers', "
+ " {{'{prefix}.102', '192.168.42.105'}}, "
+ " {{headers={{my_header='myvalue'}}}}) ")
+
+badheaders.ifurlup IN LUA A ("ifurlup('http://example.com:8080/check-headers', "
+ " {{'{prefix}.102', '192.168.42.105'}}, "
+ " {{headers={{my_header='wrong-value'}}}}) ")
+
nl IN LUA A ( ";include('config') "
"return ifportup(8081, NLips) ")
latlon.geo IN LUA TXT "latlon()"
self.assertRcodeEqual(res, dns.rcode.NOERROR)
self.assertAnyRRsetInAnswer(res, reachable_rrs)
+ def testIfurlupHeaders(self):
+ """
+ ifurlup() test where send headers.
+ """
+ reachable = [
+ '{prefix}.102'.format(prefix=self._PREFIX)
+ ]
+ unreachable = ['192.168.42.105']
+ ips = reachable + unreachable
+ all_rrs = []
+ reachable_rrs = []
+ for ip in ips:
+ rr = dns.rrset.from_text('goodheaders.ifurlup.example.org.', 0, dns.rdataclass.IN, 'A', ip)
+ all_rrs.append(rr)
+ if ip in reachable:
+ reachable_rrs.append(rr)
+
+ query = dns.message.make_query('goodheaders.ifurlup.example.org', 'A')
+ res = self.sendUDPQuery(query)
+ self.assertRcodeEqual(res, dns.rcode.NOERROR)
+ self.assertAnyRRsetInAnswer(res, all_rrs)
+
+ time.sleep(3)
+ res = self.sendUDPQuery(query)
+ self.assertRcodeEqual(res, dns.rcode.NOERROR)
+ self.assertAnyRRsetInAnswer(res, reachable_rrs)
+
+ def testIfurlupHeadersBad(self):
+ """
+ ifurlup() test where send headers, but the value is wrong
+ """
+ reachable = [
+ '{prefix}.102'.format(prefix=self._PREFIX)
+ ]
+ unreachable = ['192.168.42.105']
+ ips = reachable + unreachable
+ all_rrs = []
+ reachable_rrs = []
+ for ip in ips:
+ rr = dns.rrset.from_text('badheaders.ifurlup.example.org.', 0, dns.rdataclass.IN, 'A', ip)
+ all_rrs.append(rr)
+ if ip in reachable:
+ reachable_rrs.append(rr)
+
+ query = dns.message.make_query('badheaders.ifurlup.example.org', 'A')
+ res = self.sendUDPQuery(query)
+ self.assertRcodeEqual(res, dns.rcode.NOERROR)
+ self.assertAnyRRsetInAnswer(res, all_rrs)
+
+ time.sleep(3)
+ res = self.sendUDPQuery(query)
+ self.assertRcodeEqual(res, dns.rcode.NOERROR)
+ self.assertAnyRRsetInAnswer(res, all_rrs)
+
def testLatlon(self):
"""
Basic latlon() test