Update dependencies, fix issue with resolving SRV records

This commit is contained in:
Jacob Gunther 2024-08-10 09:48:41 -05:00
parent 2ee543a6df
commit 8b328f64f5
No known key found for this signature in database
GPG Key ID: 0BC0BF3A18802890
5 changed files with 51 additions and 68 deletions

2
go.mod
View File

@ -7,7 +7,7 @@ toolchain go1.22.3
require (
github.com/go-redsync/redsync/v4 v4.13.0
github.com/gofiber/fiber/v2 v2.52.5
github.com/mcstatus-io/mcutil/v4 v4.0.0-20240719034021-32d6524c0a5a
github.com/mcstatus-io/mcutil/v4 v4.0.0-20240810144107-526e8f097db7
github.com/redis/go-redis/v9 v9.5.4
go.mongodb.org/mongo-driver v1.16.0
gopkg.in/yaml.v3 v3.0.1

2
go.sum
View File

@ -44,6 +44,8 @@ github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZ
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mcstatus-io/mcutil/v4 v4.0.0-20240719034021-32d6524c0a5a h1:BnQPuCQvDabddAqVBjJ0US8TjI8/AKe//KkYGmZ75iM=
github.com/mcstatus-io/mcutil/v4 v4.0.0-20240719034021-32d6524c0a5a/go.mod h1:yC91WInI1U2GAMFWgpPgsAULPVS2o+4JCZbiiWhHwxM=
github.com/mcstatus-io/mcutil/v4 v4.0.0-20240810144107-526e8f097db7 h1:DaSQZf8L5ali7HmUDJq/7pf06U2yapEer3caRka5dJs=
github.com/mcstatus-io/mcutil/v4 v4.0.0-20240810144107-526e8f097db7/go.mod h1:yC91WInI1U2GAMFWgpPgsAULPVS2o+4JCZbiiWhHwxM=
github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE=
github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
github.com/redis/go-redis/v9 v9.5.4 h1:vOFYDKKVgrI5u++QvnMT7DksSMYg7Aw/Np4vLJLKLwY=

View File

@ -55,15 +55,15 @@ func PingHandler(ctx *fiber.Ctx) error {
// JavaStatusHandler returns the status of the Java edition Minecraft server specified in the address parameter.
func JavaStatusHandler(ctx *fiber.Ctx) error {
address := strings.ToLower(ctx.Params("address"))
opts, err := GetStatusOptions(ctx)
if err != nil {
return err
}
if _, _, err := util.ParseAddress(address); err != nil {
hostname, port, err := ParseAddress(strings.ToLower(ctx.Params("address")), util.DefaultJavaPort)
if err != nil {
return ctx.Status(http.StatusBadRequest).SendString("Invalid address value")
}
@ -75,11 +75,11 @@ func JavaStatusHandler(ctx *fiber.Ctx) error {
return err
}
if err = r.Increment(fmt.Sprintf("java-hits:%s", address)); err != nil {
if err = r.Increment(fmt.Sprintf("java-hits:%s", fmt.Sprintf("%s:%d", hostname, port))); err != nil {
return err
}
response, expiresAt, err := GetJavaStatus(address, opts)
response, expiresAt, err := GetJavaStatus(hostname, port, opts)
if err != nil {
return err
@ -96,23 +96,23 @@ func JavaStatusHandler(ctx *fiber.Ctx) error {
// BedrockStatusHandler returns the status of the Bedrock edition Minecraft server specified in the address parameter.
func BedrockStatusHandler(ctx *fiber.Ctx) error {
address := strings.ToLower(ctx.Params("address"))
opts, err := GetStatusOptions(ctx)
if err != nil {
return err
}
if _, _, err := util.ParseAddress(address); err != nil {
hostname, port, err := ParseAddress(strings.ToLower(ctx.Params("address")), util.DefaultBedrockPort)
if err != nil {
return ctx.Status(http.StatusBadRequest).SendString("Invalid address value")
}
if err = r.Increment(fmt.Sprintf("bedrock-hits:%s", address)); err != nil {
if err = r.Increment(fmt.Sprintf("bedrock-hits:%s", fmt.Sprintf("%s:%d", hostname, port))); err != nil {
return err
}
response, expiresAt, err := GetBedrockStatus(address, opts)
response, expiresAt, err := GetBedrockStatus(hostname, port, opts)
if err != nil {
return err
@ -129,19 +129,19 @@ func BedrockStatusHandler(ctx *fiber.Ctx) error {
// IconHandler returns the server icon for the specified Java edition Minecraft server.
func IconHandler(ctx *fiber.Ctx) error {
address := strings.ToLower(ctx.Params("address"))
opts, err := GetStatusOptions(ctx)
if err != nil {
return err
}
if _, _, err := util.ParseAddress(address); err != nil {
hostname, port, err := ParseAddress(strings.ToLower(ctx.Params("address")), util.DefaultJavaPort)
if err != nil {
return ctx.Status(http.StatusBadRequest).SendString("Invalid address value")
}
icon, expiresAt, err := GetServerIcon(address, opts)
icon, expiresAt, err := GetServerIcon(hostname, port, opts)
if err != nil {
return err

View File

@ -126,8 +126,8 @@ type SRVRecord struct {
}
// GetJavaStatus returns the status response of a Java Edition server, either using cache or fetching a fresh status.
func GetJavaStatus(host string, opts *StatusOptions) (*JavaStatusResponse, time.Duration, error) {
cacheKey := GetCacheKey(host, opts)
func GetJavaStatus(hostname string, port uint16, opts *StatusOptions) (*JavaStatusResponse, time.Duration, error) {
cacheKey := GetCacheKey(hostname, port, opts)
// Wait for any other processes to finish fetching the status of this server
if config.Cache.EnableLocks {
@ -156,7 +156,7 @@ func GetJavaStatus(host string, opts *StatusOptions) (*JavaStatusResponse, time.
// Fetch a fresh status from the server itself
{
response, err := FetchJavaStatus(host, opts)
response, err := FetchJavaStatus(hostname, port, opts)
if err != nil {
return nil, 0, err
@ -177,8 +177,8 @@ func GetJavaStatus(host string, opts *StatusOptions) (*JavaStatusResponse, time.
}
// GetBedrockStatus returns the status response of a Bedrock Edition server, either using cache or fetching a fresh status.
func GetBedrockStatus(host string, opts *StatusOptions) (*BedrockStatusResponse, time.Duration, error) {
cacheKey := GetCacheKey(host, nil)
func GetBedrockStatus(hostname string, port uint16, opts *StatusOptions) (*BedrockStatusResponse, time.Duration, error) {
cacheKey := GetCacheKey(hostname, port, nil)
// Wait for any other processes to finish fetching the status of this server
if config.Cache.EnableLocks {
@ -207,7 +207,7 @@ func GetBedrockStatus(host string, opts *StatusOptions) (*BedrockStatusResponse,
// Fetch a fresh status from the server itself
{
response, err := FetchBedrockStatus(host, opts)
response, err := FetchBedrockStatus(hostname, port, opts)
if err != nil {
return nil, 0, err
@ -228,8 +228,8 @@ func GetBedrockStatus(host string, opts *StatusOptions) (*BedrockStatusResponse,
}
// GetServerIcon returns the icon image of a Java Edition server, either using cache or fetching a fresh image.
func GetServerIcon(host string, opts *StatusOptions) ([]byte, time.Duration, error) {
cacheKey := GetCacheKey(host, nil)
func GetServerIcon(hostname string, port uint16, opts *StatusOptions) ([]byte, time.Duration, error) {
cacheKey := GetCacheKey(hostname, port, nil)
// Fetch the cached icon if it exists
{
@ -254,7 +254,7 @@ func GetServerIcon(host string, opts *StatusOptions) ([]byte, time.Duration, err
defer cancel()
status, err := status.Modern(ctx, host)
status, err := status.Modern(ctx, hostname, port)
if err == nil && status.Favicon != nil && strings.HasPrefix(*status.Favicon, "data:image/png;base64,") {
data, err := base64.StdEncoding.DecodeString(strings.TrimPrefix(*status.Favicon, "data:image/png;base64,"))
@ -278,11 +278,11 @@ func GetServerIcon(host string, opts *StatusOptions) ([]byte, time.Duration, err
}
// FetchJavaStatus fetches fresh information about a Java Edition Minecraft server.
func FetchJavaStatus(host string, opts *StatusOptions) (*JavaStatusResponse, error) {
func FetchJavaStatus(hostname string, port uint16, opts *StatusOptions) (*JavaStatusResponse, error) {
var (
err error
srvRecord *net.SRV
resolvedHost string = host
resolvedHostname string = hostname
ipAddress *string
statusResult *response.StatusModern
legacyStatusResult *response.StatusLegacy
@ -301,16 +301,16 @@ func FetchJavaStatus(host string, opts *StatusOptions) (*JavaStatusResponse, err
// Lookup the SRV record
{
srvRecord, err = util.LookupSRV(host)
srvRecord, err = util.LookupSRV(hostname)
if err == nil && srvRecord != nil {
resolvedHost = strings.Trim(srvRecord.Target, ".")
resolvedHostname = strings.Trim(srvRecord.Target, ".")
}
}
// Resolve the connection hostname to an IP address
{
addr, err := net.ResolveIPAddr("ip", resolvedHost)
addr, err := net.ResolveIPAddr("ip", resolvedHostname)
if err == nil && addr != nil {
ipAddress = PointerOf(addr.IP.String())
@ -328,11 +328,11 @@ func FetchJavaStatus(host string, opts *StatusOptions) (*JavaStatusResponse, err
// Retrieve the post-netty rewrite Java Edition status (Minecraft 1.8+)
{
go func() {
statusResult, _ = status.Modern(statusContext, host, options.StatusModern{
statusResult, _ = status.Modern(statusContext, hostname, port, options.StatusModern{
EnableSRV: true,
Timeout: opts.Timeout - time.Millisecond*100,
ProtocolVersion: 47,
Ping: false,
ProtocolVersion: -1,
Ping: true,
})
wg.Done()
@ -352,10 +352,10 @@ func FetchJavaStatus(host string, opts *StatusOptions) (*JavaStatusResponse, err
// Retrieve the pre-netty rewrite Java Edition status (Minecraft 1.7 and below)
{
go func() {
legacyStatusResult, _ = status.Legacy(legacyContext, host, options.StatusLegacy{
legacyStatusResult, _ = status.Legacy(legacyContext, hostname, port, options.StatusLegacy{
EnableSRV: true,
Timeout: opts.Timeout - time.Millisecond*100,
ProtocolVersion: 47,
ProtocolVersion: -1,
})
wg.Done()
@ -371,7 +371,7 @@ func FetchJavaStatus(host string, opts *StatusOptions) (*JavaStatusResponse, err
// Retrieve the query information (if it is available)
if opts.Query {
go func() {
queryResult, _ = query.Full(queryContext, host, options.Query{
queryResult, _ = query.Full(queryContext, hostname, port, options.Query{
Timeout: opts.Timeout - time.Millisecond*100,
})
@ -381,11 +381,11 @@ func FetchJavaStatus(host string, opts *StatusOptions) (*JavaStatusResponse, err
wg.Wait()
return BuildJavaResponse(host, statusResult, legacyStatusResult, queryResult, srvRecord, ipAddress)
return BuildJavaResponse(hostname, port, statusResult, legacyStatusResult, queryResult, srvRecord, ipAddress)
}
// FetchBedrockStatus fetches a fresh status of a Bedrock Edition server.
func FetchBedrockStatus(host string, opts *StatusOptions) (*BedrockStatusResponse, error) {
func FetchBedrockStatus(hostname string, port uint16, opts *StatusOptions) (*BedrockStatusResponse, error) {
var (
ipAddress *string
result *response.StatusBedrock
@ -393,7 +393,7 @@ func FetchBedrockStatus(host string, opts *StatusOptions) (*BedrockStatusRespons
// Resolve the connection hostname to an IP address
{
ipAddr, err := net.ResolveIPAddr("ip", host)
ipAddr, err := net.ResolveIPAddr("ip", hostname)
if err == nil && ipAddr != nil {
ipAddress = PointerOf(ipAddr.IP.String())
@ -406,31 +406,21 @@ func FetchBedrockStatus(host string, opts *StatusOptions) (*BedrockStatusRespons
defer cancel()
result, _ = status.Bedrock(ctx, host)
result, _ = status.Bedrock(ctx, hostname, port)
}
return BuildBedrockResponse(host, result, ipAddress)
return BuildBedrockResponse(hostname, port, result, ipAddress)
}
// BuildJavaResponse builds the response data from the status and query information.
func BuildJavaResponse(host string, status *response.StatusModern, legacyStatus *response.StatusLegacy, query *response.QueryFull, srvRecord *net.SRV, ipAddress *string) (result *JavaStatusResponse, err error) {
hostname, port, err := util.ParseAddress(host)
if err != nil {
return nil, err
}
if port == nil {
port = PointerOf(uint16(util.DefaultJavaPort))
}
func BuildJavaResponse(hostname string, port uint16, status *response.StatusModern, legacyStatus *response.StatusLegacy, query *response.QueryFull, srvRecord *net.SRV, ipAddress *string) (result *JavaStatusResponse, err error) {
result = &JavaStatusResponse{
BaseStatus: BaseStatus{
Online: false,
Host: hostname,
Port: *port,
Port: port,
IPAddress: ipAddress,
EULABlocked: IsBlockedAddress(host),
EULABlocked: IsBlockedAddress(hostname),
RetrievedAt: time.Now().UnixMilli(),
ExpiresAt: time.Now().Add(config.Cache.JavaStatusDuration).UnixMilli(),
},
@ -620,24 +610,14 @@ func BuildJavaResponse(host string, status *response.StatusModern, legacyStatus
}
// BuildBedrockResponse builds the response data from the status information.
func BuildBedrockResponse(host string, status *response.StatusBedrock, ipAddress *string) (result *BedrockStatusResponse, err error) {
hostname, port, err := util.ParseAddress(host)
if err != nil {
return nil, err
}
if port == nil {
port = PointerOf(uint16(util.DefaultBedrockPort))
}
func BuildBedrockResponse(hostname string, port uint16, status *response.StatusBedrock, ipAddress *string) (result *BedrockStatusResponse, err error) {
result = &BedrockStatusResponse{
BaseStatus: BaseStatus{
Online: false,
Host: hostname,
Port: *port,
Port: port,
IPAddress: ipAddress,
EULABlocked: IsBlockedAddress(host),
EULABlocked: IsBlockedAddress(hostname),
RetrievedAt: time.Now().UnixMilli(),
ExpiresAt: time.Now().Add(config.Cache.BedrockStatusDuration).UnixMilli(),
},

View File

@ -270,9 +270,10 @@ func GetInstanceID() (uint16, error) {
}
// GetCacheKey generates a unique key used for caching status results in Redis.
func GetCacheKey(host string, opts *StatusOptions) string {
func GetCacheKey(hostname string, port uint16, opts *StatusOptions) string {
values := &url.Values{}
values.Set("host", host)
values.Set("hostname", hostname)
values.Set("port", strconv.FormatUint(uint64(port), 10))
if opts != nil {
values.Set("query", strconv.FormatBool(opts.Query))