Routes Java Edition connections by the hostname in the handshake, with wildcard domains, backend failover, PROXY protocol v2, cached server-list status from health probes, hot-reloaded config, and an admin page and metrics endpoint. Includes CI, tagged releases and a container image. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e640c5bf02
commit
b53af0e196
29 files changed
+2640
No files matched your search
@@ -0,0 +1,87 @@
|
||||
package protocol
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestHandshakeRoundTrip(t *testing.T) {
|
||||
in := BuildHandshake(767, "mc.example.com", 25565, 2)
|
||||
h, raw, err := ReadHandshake(bytes.NewReader(in))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
want := Handshake{Protocol: 767, Host: "mc.example.com", Port: 25565, NextState: 2}
|
||||
if h != want {
|
||||
t.Fatalf("got %+v want %+v", h, want)
|
||||
}
|
||||
if !bytes.Equal(raw, in) {
|
||||
t.Fatal("raw bytes not preserved")
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadHandshakeRejects(t *testing.T) {
|
||||
cases := map[string][]byte{
|
||||
"legacy": {0xfe, 0x01, 0xfa},
|
||||
"huge length": {0xff, 0xff, 0xff, 0xff, 0x07},
|
||||
"zero length": {0x00},
|
||||
"wrong id": Frame([]byte{0x05, 0x00}),
|
||||
"short host": Frame([]byte{0x00, 0x01, 0x40, 'a'}),
|
||||
"truncated": {0x10, 0x00},
|
||||
}
|
||||
for name, b := range cases {
|
||||
if _, _, err := ReadHandshake(bytes.NewReader(b)); err == nil {
|
||||
t.Errorf("%s: expected error", name)
|
||||
}
|
||||
}
|
||||
if _, _, err := ReadHandshake(bytes.NewReader([]byte{0xfe, 0x01})); err != ErrLegacy {
|
||||
t.Errorf("want ErrLegacy, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVarInt(t *testing.T) {
|
||||
if got := AppendVarInt(nil, 300); !bytes.Equal(got, []byte{0xac, 0x02}) {
|
||||
t.Fatalf("got %x", got)
|
||||
}
|
||||
if got := AppendVarInt(nil, -1); len(got) != 5 {
|
||||
t.Fatalf("negative should take 5 bytes, got %x", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStatusExchange(t *testing.T) {
|
||||
c, s := net.Pipe()
|
||||
defer c.Close()
|
||||
go func() {
|
||||
defer s.Close()
|
||||
ServeStatus(s, `{"ok":true}`)
|
||||
}()
|
||||
c.SetDeadline(time.Now().Add(2 * time.Second))
|
||||
c.Write(Frame([]byte{0}))
|
||||
id, payload, err := ReadPacket(c, maxStatus)
|
||||
if err != nil || id != 0 || !bytes.Contains(payload, []byte(`{"ok":true}`)) {
|
||||
t.Fatalf("id=%d payload=%q err=%v", id, payload, err)
|
||||
}
|
||||
c.Write(Frame(append([]byte{1}, 0, 0, 0, 0, 0, 0, 0, 42)))
|
||||
id, payload, err = ReadPacket(c, 32)
|
||||
if err != nil || id != 1 || payload[7] != 42 {
|
||||
t.Fatalf("pong id=%d payload=%x err=%v", id, payload, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestQueryStatus(t *testing.T) {
|
||||
c, s := net.Pipe()
|
||||
defer c.Close()
|
||||
go func() {
|
||||
defer s.Close()
|
||||
if _, _, err := ReadHandshake(s); err != nil {
|
||||
return
|
||||
}
|
||||
ServeStatus(s, `{"players":{"online":3}}`)
|
||||
}()
|
||||
got, err := QueryStatus(c, "x", 25565, 2*time.Second)
|
||||
if err != nil || got != `{"players":{"online":3}}` {
|
||||
t.Fatalf("got %q err=%v", got, err)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user