Compare commits

...
Author SHA1 Message Date
RMT c06eb0d331 WIP 2026-04-26 22:18:07 +08:00
RMT c8b48dc248 WIP 2026-04-26 22:18:07 +08:00
azoway 45d94cf391 Update install.sh
在alpine服务器上运行安装脚本报错:
curl: (3) URL rejected: Malformed input to a URL function

排查后发现,当前版本部分会匹配出来2个版本的下载链接:
gost_3.2.6_linux_amd64.tar.gz
gost_3.2.6_linux_amd64v3.tar.gz

修改后默认取第一个兼容性更好的版本
2026-04-26 22:16:06 +08:00
7 changed files with 183 additions and 2 deletions
+1 -1
View File
@@ -35,6 +35,6 @@ cmd/gost/gost
snap
*.pem
*.yaml
/*.yaml
*.txt
dist/
+1 -1
View File
@@ -66,7 +66,7 @@ install_gost() {
;;
esac
get_download_url="$base_url/tags/$version"
download_url=$(curl -s "$get_download_url" | awk -F'"' -v re=".*${os}.*${cpu_arch}.*" '/"browser_download_url":/ && $4 ~ re { print $4 }')
download_url=$(curl -s "$get_download_url" | awk -F'"' -v re=".*${os}.*${cpu_arch}.*" '/"browser_download_url":/ && $4 ~ re { print $4 }' | head -n 1)
# Download and install the binary
install_path="/usr/local/bin"
+4
View File
@@ -0,0 +1,4 @@
FROM alpine:3.22
# add iptables for tun/tap and curl for testing
RUN apk add --no-cache iptables curl
+46
View File
@@ -0,0 +1,46 @@
package e2e
import (
"context"
"fmt"
"os"
"os/exec"
"testing"
"github.com/testcontainers/testcontainers-go/network"
)
var SharedNetworkName string
func TestMain(m *testing.M) {
ctx := context.Background()
// Compile the gost binary
cmd := exec.Command("go", "build", "-o", "/tmp/gost-test-bin", "../../cmd/gost")
cmd.Env = append(os.Environ(), "CGO_ENABLED=0")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
fmt.Printf("Failed to compile gost: %v\n", err)
os.Exit(1)
}
defer func() {
os.Remove("/tmp/gost-test-bin")
}()
// Create a shared Docker network
net, err := network.New(ctx)
if err != nil {
fmt.Printf("Failed to create network: %v\n", err)
os.Exit(1)
}
SharedNetworkName = net.Name
// Run tests
code := m.Run()
// Cleanup
net.Remove(ctx)
os.Exit(code)
}
+57
View File
@@ -0,0 +1,57 @@
package e2e
import (
"context"
"fmt"
"io"
"testing"
"github.com/stretchr/testify/suite"
"github.com/testcontainers/testcontainers-go"
)
type ParallelSelectorSuite struct {
suite.Suite
ctx context.Context
echoC testcontainers.Container
echoIP string
}
func (s *ParallelSelectorSuite) SetupSuite() {
s.ctx = context.Background()
echoC, err := RunEchoContainer(s.ctx, SharedNetworkName)
s.Require().NoError(err)
s.echoC = echoC
echoIP, err := echoC.ContainerIP(s.ctx)
s.Require().NoError(err)
s.echoIP = echoIP
}
func (s *ParallelSelectorSuite) TearDownSuite() {
if s.echoC != nil {
s.echoC.Terminate(s.ctx)
}
}
func (s *ParallelSelectorSuite) TestParallelSelector() {
gostC, err := RunGostContainer(s.ctx, SharedNetworkName, "testdata/parallel_selector/server.yaml")
s.Require().NoError(err)
defer gostC.Terminate(s.ctx)
// Test the proxy by running curl inside the gost container
cmd := []string{"curl", "-v", "-s", "-x", "http://127.0.0.1:8080", fmt.Sprintf("http://%s:5678", s.echoIP)}
code, out, err := gostC.Exec(s.ctx, cmd)
s.Require().NoError(err)
body, err := io.ReadAll(out)
s.Require().NoError(err)
s.Require().Equal(0, code)
s.Require().Contains(string(body), "hello-gost")
}
func TestParallelSelectorSuite(t *testing.T) {
suite.Run(t, new(ParallelSelectorSuite))
}
+30
View File
@@ -0,0 +1,30 @@
services:
- name: proxy
addr: :8080
handler:
type: http
chain: my-chain
listener:
type: tcp
- name: dummy-1
addr: :18081
handler:
type: http
chains:
- name: my-chain
hops:
- name: hop-1
selector:
strategy: parallel
nodes:
- name: node-1
addr: 127.0.0.1:18081
connector:
type: http
# non existed node
- name: node-2
addr: 127.0.0.1:18082
connector:
type: http
+44
View File
@@ -0,0 +1,44 @@
package e2e
import (
"context"
"github.com/testcontainers/testcontainers-go"
"github.com/testcontainers/testcontainers-go/wait"
)
func RunEchoContainer(ctx context.Context, networkName string) (testcontainers.Container, error) {
req := testcontainers.ContainerRequest{
Image: "hashicorp/http-echo:latest",
Networks: []string{networkName},
Cmd: []string{"-text=hello-gost", "-listen=:5678"},
ExposedPorts: []string{"5678/tcp"},
WaitingFor: wait.ForHTTP("/").WithPort("5678/tcp"),
}
return testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
ContainerRequest: req,
Started: true,
})
}
func RunGostContainer(ctx context.Context, networkName, yamlPath string) (testcontainers.Container, error) {
req := testcontainers.ContainerRequest{
FromDockerfile: testcontainers.FromDockerfile{
Context: ".",
Dockerfile: "Dockerfile",
Repo: "gost-e2e",
Tag: "latest",
KeepImage: true,
},
Networks: []string{networkName},
Files: []testcontainers.ContainerFile{
{HostFilePath: "/tmp/gost-test-bin", ContainerFilePath: "/bin/gost", FileMode: 0755},
{HostFilePath: yamlPath, ContainerFilePath: "/config.yaml", FileMode: 0644},
},
Cmd: []string{"/bin/gost", "-C", "/config.yaml"},
}
return testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
ContainerRequest: req,
Started: true,
})
}