Skip to content

Commit 230da56

Browse files
committed
[Bug] Fix the issue that requests may hang
1 parent 4ea9ba5 commit 230da56

File tree

2 files changed

+57
-29
lines changed

2 files changed

+57
-29
lines changed

cloudflare-ddns.py

Lines changed: 54 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,14 @@
1515
import threading
1616
import time
1717
import requests
18+
import logging
1819

1920
CONFIG_PATH = os.environ.get('CONFIG_PATH', os.getcwd())
21+
FORMATTER = logging.Formatter("%(asctime)s — %(name)s — %(levelname)s — %(message)s")
2022

23+
def getLogger():
24+
logger = logging.getLogger(__name__)
25+
return logger
2126

2227
class GracefulExit:
2328
def __init__(self):
@@ -26,7 +31,7 @@ def __init__(self):
2631
signal.signal(signal.SIGTERM, self.exit_gracefully)
2732

2833
def exit_gracefully(self, signum, frame):
29-
print("🛑 Stopping main thread...")
34+
getLogger().info("🛑 Stopping main thread...")
3035
self.kill_now.set()
3136

3237

@@ -47,7 +52,7 @@ def deleteEntries(type):
4752
cf_api(
4853
"zones/" + option['zone_id'] + "/dns_records/" + identifier,
4954
"DELETE", option)
50-
print("🗑️ Deleted stale record " + identifier)
55+
getLogger().info("🗑️ Deleted stale record " + identifier)
5156

5257

5358
def getIPs():
@@ -56,51 +61,52 @@ def getIPs():
5661
global ipv4_enabled
5762
global ipv6_enabled
5863
global purgeUnknownRecords
64+
global timeout
5965
if ipv4_enabled:
6066
try:
6167
a = requests.get(
62-
"https://1.1.1.1/cdn-cgi/trace").text.split("\n")
68+
"https://1.1.1.1/cdn-cgi/trace", timeout=timeout).text.split("\n")
6369
a.pop()
6470
a = dict(s.split("=") for s in a)["ip"]
6571
except Exception:
6672
global shown_ipv4_warning
6773
if not shown_ipv4_warning:
6874
shown_ipv4_warning = True
69-
print("🧩 IPv4 not detected via 1.1.1.1, trying 1.0.0.1")
75+
getLogger().info("🧩 IPv4 not detected via 1.1.1.1, trying 1.0.0.1")
7076
# Try secondary IP check
7177
try:
7278
a = requests.get(
73-
"https://1.0.0.1/cdn-cgi/trace").text.split("\n")
79+
"https://1.0.0.1/cdn-cgi/trace", timeout=timeout).text.split("\n")
7480
a.pop()
7581
a = dict(s.split("=") for s in a)["ip"]
7682
except Exception:
7783
global shown_ipv4_warning_secondary
7884
if not shown_ipv4_warning_secondary:
7985
shown_ipv4_warning_secondary = True
80-
print("🧩 IPv4 not detected via 1.0.0.1. Verify your ISP or DNS provider isn't blocking Cloudflare's IPs.")
86+
getLogger().info("🧩 IPv4 not detected via 1.0.0.1. Verify your ISP or DNS provider isn't blocking Cloudflare's IPs.")
8187
if purgeUnknownRecords:
8288
deleteEntries("A")
8389
if ipv6_enabled:
8490
try:
8591
aaaa = requests.get(
86-
"https://[2606:4700:4700::1111]/cdn-cgi/trace").text.split("\n")
92+
"https://[2606:4700:4700::1111]/cdn-cgi/trace", timeout=timeout).text.split("\n")
8793
aaaa.pop()
8894
aaaa = dict(s.split("=") for s in aaaa)["ip"]
8995
except Exception:
9096
global shown_ipv6_warning
9197
if not shown_ipv6_warning:
9298
shown_ipv6_warning = True
93-
print("🧩 IPv6 not detected via 1.1.1.1, trying 1.0.0.1")
99+
getLogger().info("🧩 IPv6 not detected via 1.1.1.1, trying 1.0.0.1")
94100
try:
95101
aaaa = requests.get(
96-
"https://[2606:4700:4700::1001]/cdn-cgi/trace").text.split("\n")
102+
"https://[2606:4700:4700::1001]/cdn-cgi/trace", timeout=timeout).text.split("\n")
97103
aaaa.pop()
98104
aaaa = dict(s.split("=") for s in aaaa)["ip"]
99105
except Exception:
100106
global shown_ipv6_warning_secondary
101107
if not shown_ipv6_warning_secondary:
102108
shown_ipv6_warning_secondary = True
103-
print("🧩 IPv6 not detected via 1.0.0.1. Verify your ISP or DNS provider isn't blocking Cloudflare's IPs.")
109+
getLogger().info("🧩 IPv6 not detected via 1.0.0.1. Verify your ISP or DNS provider isn't blocking Cloudflare's IPs.")
104110
if purgeUnknownRecords:
105111
deleteEntries("AAAA")
106112
ips = {}
@@ -166,23 +172,24 @@ def commitRecord(ip):
166172
modified = True
167173
if identifier:
168174
if modified:
169-
print("📡 Updating record " + str(record))
175+
getLogger().info("📡 Updating record " + str(record))
170176
response = cf_api(
171177
"zones/" + option['zone_id'] +
172178
"/dns_records/" + identifier,
173179
"PUT", option, {}, record)
174180
else:
175-
print("➕ Adding new record " + str(record))
181+
getLogger().info("➕ Adding new record " + str(record))
176182
response = cf_api(
177183
"zones/" + option['zone_id'] + "/dns_records", "POST", option, {}, record)
178184
if purgeUnknownRecords:
179185
for identifier in duplicate_ids:
180186
identifier = str(identifier)
181-
print("🗑️ Deleting stale record " + identifier)
187+
getLogger().info("🗑️ Deleting stale record " + identifier)
182188
response = cf_api(
183189
"zones/" + option['zone_id'] +
184190
"/dns_records/" + identifier,
185191
"DELETE", option)
192+
getLogger().debug("📡 Updated ip " + str(ip))
186193
return True
187194

188195

@@ -220,21 +227,21 @@ def cf_api(endpoint, method, config, headers={}, data=False):
220227
try:
221228
if (data == False):
222229
response = requests.request(
223-
method, "https://api.cloudflare.com/client/v4/" + endpoint, headers=headers)
230+
method, "https://api.cloudflare.com/client/v4/" + endpoint, headers=headers, timeout=timeout)
224231
else:
225232
response = requests.request(
226233
method, "https://api.cloudflare.com/client/v4/" + endpoint,
227-
headers=headers, json=data)
234+
headers=headers, json=data, timeout=timeout)
228235

229236
if response.ok:
230237
return response.json()
231238
else:
232-
print("😡 Error sending '" + method +
239+
getLogger().info("😡 Error sending '" + method +
233240
"' request to '" + response.url + "':")
234-
print(response.text)
241+
getLogger().info(response.text)
235242
return None
236243
except Exception as e:
237-
print("😡 An exception occurred while sending '" +
244+
getLogger().info("😡 An exception occurred while sending '" +
238245
method + "' request to '" + endpoint + "': " + str(e))
239246
return None
240247

@@ -253,6 +260,13 @@ def updateIPs(ips):
253260
ipv4_enabled = True
254261
ipv6_enabled = True
255262
purgeUnknownRecords = False
263+
timeout = 15
264+
logging_level = 'INFO'
265+
logger = getLogger()
266+
logging_handler = logging.StreamHandler(sys.stdout)
267+
logging_handler.setFormatter(FORMATTER)
268+
logger.addHandler(logging_handler)
269+
logger.setLevel(logging.getLevelName(logging_level))
256270

257271
if sys.version_info < (3, 5):
258272
raise Exception("🐍 This script requires Python 3.5+")
@@ -267,37 +281,49 @@ def updateIPs(ips):
267281
time.sleep(10)
268282

269283
if config is not None:
284+
try:
285+
logging_level = config["logging"]
286+
logger.setLevel(logging.getLevelName(logging_level))
287+
except:
288+
getLogger().info("⚙️ Error config logger - defaulting to INFO")
289+
logger.setLevel(logging.INFO)
270290
try:
271291
ipv4_enabled = config["a"]
272292
ipv6_enabled = config["aaaa"]
273293
except:
274294
ipv4_enabled = True
275295
ipv6_enabled = True
276-
print("⚙️ Individually disable IPv4 or IPv6 with new config.json options. Read more about it here: https://github.com/timothymiller/cloudflare-ddns/blob/master/README.md")
296+
getLogger().info("⚙️ Individually disable IPv4 or IPv6 with new config.json options. Read more about it here: https://github.com/timothymiller/cloudflare-ddns/blob/master/README.md")
277297
try:
278298
purgeUnknownRecords = config["purgeUnknownRecords"]
279299
except:
280300
purgeUnknownRecords = False
281-
print("⚙️ No config detected for 'purgeUnknownRecords' - defaulting to False")
301+
getLogger().info("⚙️ No config detected for 'purgeUnknownRecords' - defaulting to False")
282302
try:
283303
ttl = int(config["ttl"])
284304
except:
285305
ttl = 300 # default Cloudflare TTL
286-
print(
287-
"⚙️ No config detected for 'ttl' - defaulting to 300 seconds (5 minutes)")
306+
getLogger().info("⚙️ No config detected for 'ttl' - defaulting to 300 seconds (5 minutes)")
288307
if ttl < 30:
289308
ttl = 1 #
290-
print("⚙️ TTL is too low - defaulting to 1 (auto)")
309+
getLogger().info("⚙️ TTL is too low - defaulting to 1 (auto)")
310+
try:
311+
timeout = int(config["timeout"])
312+
except:
313+
timeout = ttl
314+
getLogger().info("⚙️ No config detected for 'timeout' - defaulting to %d seconds", timeout)
315+
if timeout < 10:
316+
timeout = 10
317+
getLogger().info("⚙️ Timeout is too low - defaulting to %d seconds", timeout)
291318
if (len(sys.argv) > 1):
292319
if (sys.argv[1] == "--repeat"):
293320
if ipv4_enabled and ipv6_enabled:
294-
print(
295-
"🕰️ Updating IPv4 (A) & IPv6 (AAAA) records every " + str(ttl) + " seconds")
321+
getLogger().info("🕰️ Updating IPv4 (A) & IPv6 (AAAA) records every " + str(ttl) + " seconds")
296322
elif ipv4_enabled and not ipv6_enabled:
297-
print("🕰️ Updating IPv4 (A) records every " +
323+
getLogger().info("🕰️ Updating IPv4 (A) records every " +
298324
str(ttl) + " seconds")
299325
elif ipv6_enabled and not ipv4_enabled:
300-
print("🕰️ Updating IPv6 (AAAA) records every " +
326+
getLogger().info("🕰️ Updating IPv6 (AAAA) records every " +
301327
str(ttl) + " seconds")
302328
next_time = time.time()
303329
killer = GracefulExit()
@@ -307,7 +333,7 @@ def updateIPs(ips):
307333
if killer.kill_now.wait(ttl):
308334
break
309335
else:
310-
print("❓ Unrecognized parameter '" +
336+
getLogger().info("❓ Unrecognized parameter '" +
311337
sys.argv[1] + "'. Stopping now.")
312338
else:
313339
updateIPs(getIPs())

config-example.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,7 @@
2424
"a": true,
2525
"aaaa": true,
2626
"purgeUnknownRecords": false,
27-
"ttl": 300
27+
"ttl": 300,
28+
"timeout": 15,
29+
"logging": "INFO"
2830
}

0 commit comments

Comments
 (0)