mirror of
https://github.com/woodchen-ink/proxy-go.git
synced 2025-07-18 16:41:54 +08:00
first commit
This commit is contained in:
commit
6762c822ab
84
.github/workflows/docker-build.yml
vendored
Normal file
84
.github/workflows/docker-build.yml
vendored
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
name: Build and Push Docker Image
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ main ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ main ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
arch: [amd64, arm64]
|
||||||
|
include:
|
||||||
|
- arch: amd64
|
||||||
|
goarch: amd64
|
||||||
|
- arch: arm64
|
||||||
|
goarch: arm64
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Set up Go
|
||||||
|
uses: actions/setup-go@v2
|
||||||
|
with:
|
||||||
|
go-version: '1.21'
|
||||||
|
|
||||||
|
- name: Build binary
|
||||||
|
env:
|
||||||
|
GOOS: linux
|
||||||
|
GOARCH: ${{ matrix.goarch }}
|
||||||
|
CGO_ENABLED: 0
|
||||||
|
run: |
|
||||||
|
go build -o proxy-go-${{ matrix.arch }}
|
||||||
|
|
||||||
|
- name: Upload binary artifact
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: proxy-go-${{ matrix.arch }}
|
||||||
|
path: proxy-go-${{ matrix.arch }}
|
||||||
|
|
||||||
|
docker:
|
||||||
|
needs: build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Download all artifacts
|
||||||
|
uses: actions/download-artifact@v2
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v1
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v1
|
||||||
|
|
||||||
|
- name: Login to Docker Hub
|
||||||
|
uses: docker/login-action@v1
|
||||||
|
with:
|
||||||
|
username: woodchen
|
||||||
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Get current date
|
||||||
|
id: date
|
||||||
|
run: echo "::set-output name=date::$(date +'%Y%m%d')"
|
||||||
|
|
||||||
|
- name: Prepare binaries
|
||||||
|
run: |
|
||||||
|
chmod +x proxy-go-*/proxy-go-*
|
||||||
|
mv proxy-go-amd64/proxy-go-amd64 proxy-go-amd64/proxy-go
|
||||||
|
mv proxy-go-arm64/proxy-go-arm64 proxy-go-arm64/proxy-go
|
||||||
|
|
||||||
|
- name: Build and push Docker images
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
|
push: true
|
||||||
|
tags: |
|
||||||
|
woodchen/proxy-go:latest
|
||||||
|
${{ secrets.DOCKERHUB_USERNAME }}/proxy-go:${{ steps.date.outputs.date }}
|
||||||
|
|
13
Dockerfile
Normal file
13
Dockerfile
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
FROM alpine:latest
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
COPY proxy-go /app/
|
||||||
|
RUN mkdir -p /app/data && \
|
||||||
|
chmod +x /app/proxy-go && \
|
||||||
|
apk add --no-cache ca-certificates tzdata && \
|
||||||
|
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
|
||||||
|
echo "Asia/Shanghai" > /etc/timezone
|
||||||
|
|
||||||
|
EXPOSE 80
|
||||||
|
VOLUME ["/app/data"]
|
||||||
|
ENTRYPOINT ["/app/proxy-go"]
|
6
data/config.json
Normal file
6
data/config.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"MAP":{
|
||||||
|
"/path1": "https://path1.com/path/path/path",
|
||||||
|
"/path2": "https://path2.com"
|
||||||
|
}
|
||||||
|
}
|
105
main.go
Normal file
105
main.go
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Config 结构体用于解析配置文件
|
||||||
|
type Config struct {
|
||||||
|
MAP map[string]string `json:"MAP"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// 读取配置文件
|
||||||
|
configFile, err := os.ReadFile("data/config.json")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error reading config file:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析配置文件
|
||||||
|
var config Config
|
||||||
|
if err := json.Unmarshal(configFile, &config); err != nil {
|
||||||
|
log.Fatal("Error parsing config file:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建 HTTP 处理函数
|
||||||
|
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// 处理根路径请求
|
||||||
|
if r.URL.Path == "/" {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprint(w, "Welcome to CZL proxy.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查找匹配的代理路径
|
||||||
|
var matchedPrefix string
|
||||||
|
var targetBase string
|
||||||
|
for prefix, target := range config.MAP {
|
||||||
|
if strings.HasPrefix(r.URL.Path, prefix) {
|
||||||
|
matchedPrefix = prefix
|
||||||
|
targetBase = target
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果没有匹配的路径,返回 404
|
||||||
|
if matchedPrefix == "" {
|
||||||
|
http.NotFound(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建目标 URL
|
||||||
|
targetPath := strings.TrimPrefix(r.URL.Path, matchedPrefix)
|
||||||
|
targetURL := targetBase + targetPath
|
||||||
|
|
||||||
|
// 创建新的请求
|
||||||
|
proxyReq, err := http.NewRequest(r.Method, targetURL, r.Body)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "Error creating proxy request", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 复制原始请求的 header
|
||||||
|
for header, values := range r.Header {
|
||||||
|
for _, value := range values {
|
||||||
|
proxyReq.Header.Add(header, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送代理请求
|
||||||
|
client := &http.Client{}
|
||||||
|
resp, err := client.Do(proxyReq)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "Error forwarding request", http.StatusBadGateway)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
// 复制响应 header
|
||||||
|
for header, values := range resp.Header {
|
||||||
|
for _, value := range values {
|
||||||
|
w.Header().Add(header, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置响应状态码
|
||||||
|
w.WriteHeader(resp.StatusCode)
|
||||||
|
|
||||||
|
// 复制响应体
|
||||||
|
if _, err := io.Copy(w, resp.Body); err != nil {
|
||||||
|
log.Printf("Error copying response: %v", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 启动服务器
|
||||||
|
log.Println("Starting proxy server on :80")
|
||||||
|
if err := http.ListenAndServe(":80", nil); err != nil {
|
||||||
|
log.Fatal("Error starting server:", err)
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user