-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
perf: check internet with DNS lookup (#1034)
DNS lookups are much cheaper than HTTP requests since we only need to check if the Internet is available. See: https://stackoverflow.com/a/50058255
- Loading branch information
1 parent
ea85383
commit ae0f47f
Showing
8 changed files
with
158 additions
and
90 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
// Package internet implements utilities for checking the Internet connection. | ||
package internet | ||
|
||
import ( | ||
"strings" | ||
"time" | ||
|
||
"github.com/jeessy2/ddns-go/v6/util" | ||
) | ||
|
||
const ( | ||
// fallbackDNS used when a fallback occurs. | ||
fallbackDNS = "1.1.1.1" | ||
|
||
// delay is the delay time for each DNS lookup. | ||
delay = time.Second * 5 | ||
) | ||
|
||
// Wait blocks until the Internet is connected. | ||
// | ||
// See also: | ||
// | ||
// - https://stackoverflow.com/a/50058255 | ||
// - https://github.com/ddev/ddev/blob/v1.22.7/pkg/globalconfig/global_config.go#L776 | ||
func Wait(addresses []string) { | ||
// fallbase in case loopback DNS is unavailable and only once. | ||
fallback := false | ||
|
||
for { | ||
for _, addr := range addresses { | ||
err := util.LookupHost(addr) | ||
// Internet is connected. | ||
if err == nil { | ||
return | ||
} | ||
|
||
if !fallback && isLoopback(err) { | ||
util.Log("本机DNS异常! 将默认使用 %s, 可参考文档通过 -dns 自定义 DNS 服务器", fallbackDNS) | ||
util.SetDNS(fallbackDNS) | ||
|
||
fallback = true | ||
continue | ||
} | ||
|
||
util.Log("等待网络连接: %s", err) | ||
|
||
util.Log("%s 后重试...", delay) | ||
time.Sleep(delay) | ||
} | ||
} | ||
} | ||
|
||
// isLoopback checks if the error is a loopback error. | ||
func isLoopback(e error) bool { | ||
return strings.Contains(e.Error(), "[::1]:53") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,28 +1,38 @@ | ||
package util | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
import "testing" | ||
|
||
const ( | ||
testDNS = "1.1.1.1" | ||
testURL = "https://cloudflare.com" | ||
) | ||
|
||
// TestNewDialerResolver 测试传递 DNS 服务器地址时能否设置 dialer.Resolver。 | ||
func TestNewDialerResolver(t *testing.T) { | ||
// 测试前重置以确保正常设置 | ||
dialer.Resolver = nil | ||
func TestSetDNS(t *testing.T) { | ||
SetDNS(testDNS) | ||
|
||
NewDialerResolver("1.1.1.1:53") | ||
if dialer.Resolver == nil { | ||
t.Error("Failed to set dialer.Resolver") | ||
} | ||
|
||
// 测试后重置以确保与测试前的值一致 | ||
dialer.Resolver = nil | ||
} | ||
|
||
// TestNewNetResolver 测试能否通过 newNetResolver 返回的 net.Resolver 解析域名的 IP。 | ||
func TestNewNetResolver(t *testing.T) { | ||
_, err := newNetResolver("1.1.1.1:53").LookupIP(context.Background(), "ip", "cloudflare.com") | ||
if err != nil { | ||
t.Errorf("Failed to lookup IP, err: %v", err) | ||
} | ||
func TestLookupHost(t *testing.T) { | ||
t.Run("Valid URL", func(t *testing.T) { | ||
if err := LookupHost(testURL); err != nil { | ||
t.Errorf("Expected nil error, got %v", err) | ||
} | ||
}) | ||
|
||
t.Run("Invalid URL", func(t *testing.T) { | ||
if err := LookupHost("invalidurl"); err == nil { | ||
t.Error("Expected error, got nil") | ||
} | ||
}) | ||
|
||
t.Run("After SetDNS", func(t *testing.T) { | ||
SetDNS(testDNS) | ||
|
||
if err := LookupHost(testURL); err != nil { | ||
t.Errorf("Expected nil error, got %v", err) | ||
} | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package util | ||
|
||
import "testing" | ||
|
||
func TestWriteString(t *testing.T) { | ||
tests := []struct { | ||
input []string | ||
expected string | ||
}{ | ||
{[]string{"hello", "world"}, "helloworld"}, | ||
{[]string{"", "test"}, "test"}, | ||
{[]string{"hello", " ", "world"}, "hello world"}, | ||
{[]string{""}, ""}, | ||
} | ||
|
||
for _, tt := range tests { | ||
result := WriteString(tt.input...) | ||
if result != tt.expected { | ||
t.Errorf("Expected %s, but got %s", tt.expected, result) | ||
} | ||
} | ||
} | ||
|
||
func TestToHostname(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
input string | ||
expected string | ||
}{ | ||
{"With https scheme", "https://www.example.com", "www.example.com"}, | ||
{"With path", "www.example.com/path", "www.example.com"}, | ||
{"With https scheme and path", "https://www.example.com/path", "www.example.com"}, | ||
} | ||
|
||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
result := toHostname(tt.input) | ||
if result != tt.expected { | ||
t.Errorf("Expected %s, but got %s", tt.expected, result) | ||
} | ||
}) | ||
} | ||
} |