from flask import Flask, request, Response import requests from cachetools import TTLCache app = Flask(__name__) cache = TTLCache(maxsize=1000000, ttl=30000) NEXTDNS_ENDPOINT = "https://dns.nextdns.io/7df33f" total_requests = 0 cache_misses = 0 cache_hits = 0 @app.route('/', methods=['GET', 'POST']) def handle_request(): global total_requests, cache_misses, cache_hits total_requests += 1 if request.method == 'GET' and 'dns' in request.args: dns_query = request.args.get('dns') cached_response = cache.get(dns_query) if cached_response: cache_hits += 1 return Response(cached_response, mimetype='application/dns-message') else: cache_misses += 1 response = requests.get(f"{NEXTDNS_ENDPOINT}?dns={dns_query}", headers={'Accept': 'application/dns-message'}) if response.status_code == 200: cache[dns_query] = response.content return Response(response.content, mimetype='application/dns-message') elif request.method == 'POST' and request.headers.get('Content-Type') == 'application/dns-message': dns_query = request.data cached_response = cache.get(dns_query) if cached_response: cache_hits += 1 return Response(cached_response, mimetype='application/dns-message') else: cache_misses += 1 response = requests.post(NEXTDNS_ENDPOINT, headers={'Accept': 'application/dns-message', 'Content-Type': 'application/dns-message'}, data=dns_query) if response.status_code == 200: cache[dns_query] = response.content return Response(response.content, mimetype='application/dns-message') elif request.method == 'GET' and request.headers.get('Accept') == 'application/dns-json': total_requests += 1 cache_misses += 1 response = requests.get(NEXTDNS_ENDPOINT + request.full_path, headers={'Accept': 'application/dns-json'}) return Response(response.content, mimetype='application/dns-json') else: return Response("DoH Gateway Provided by NextDNS", status=444) @app.route('/stats') def show_stats(): stats = f""" ============ Total DNS Request: {total_requests} Domain Cached: {cache_misses} Domain Cached Hit: {cache_hits} ============ """ return stats if __name__ == '__main__': app.run(debug=True, threaded=True, host="0.0.0.0", port=7860)