Skip to content

Commit 1d3cc71

Browse files
committed
🎉 Initial Commit
Signed-off-by: Teakowa <27560638+Teakowa@users.noreply.github.com>
0 parents  commit 1d3cc71

6 files changed

Lines changed: 213 additions & 0 deletions

File tree

‎.github/workflows/ci.yml‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
name: Continuous Integration
2+
on:
3+
push:
4+
branches:
5+
- '**'
6+
pull_request:
7+
branches:
8+
- '**'
9+
jobs:
10+
lint:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v3
14+
- uses: actions/setup-go@v3
15+
with:
16+
go-version: 1.20
17+
- uses: golangci/golangci-lint-action@v3
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
name: Images
2+
3+
on:
4+
schedule:
5+
- cron: '0 10 * * *' # everyday at 10am UTC
6+
release:
7+
types: [ published ]
8+
push:
9+
branches:
10+
- main
11+
tags:
12+
- 'v*'
13+
paths-ignore:
14+
- '.github'
15+
workflow_dispatch:
16+
17+
jobs:
18+
docker:
19+
name: "Build & Push"
20+
runs-on: ubuntu-latest
21+
permissions:
22+
contents: read
23+
packages: write
24+
steps:
25+
- name: Checkout repository
26+
uses: actions/checkout@v3
27+
-
28+
name: Set up QEMU
29+
uses: docker/setup-qemu-action@v2
30+
-
31+
name: Set up Docker Buildx
32+
uses: docker/setup-buildx-action@v2
33+
34+
- name: Split repo name
35+
uses: jungwinter/split@v2
36+
id: split_reponame
37+
with:
38+
separator: '/'
39+
msg: ${{ github.repository }}
40+
41+
- name: Setup repo name to lowercase
42+
id: reponame
43+
uses: ASzc/change-string-case-action@v5
44+
with:
45+
string: ${{ steps.split_reponame.outputs._1 }}
46+
47+
- name: Log in to the Container registry
48+
uses: docker/login-action@v2
49+
with:
50+
registry: ${{ secrets.REGISTRY }}
51+
username: ${{ secrets.AWS_ACCESS_KEY_ID }}
52+
password: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
53+
54+
- name: Extract metadata (tags, labels) for Docker
55+
id: meta
56+
uses: docker/metadata-action@v4
57+
with:
58+
images: ${{ secrets.REGISTRY }}/${{ steps.reponame.outputs.lowercase }}
59+
60+
- name: Build and push Docker image
61+
uses: docker/build-push-action@v4
62+
with:
63+
context: .
64+
push: true
65+
tags: ${{ steps.meta.outputs.tags }}
66+
labels: ${{ steps.meta.outputs.labels }}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
- rc
8+
- beta
9+
- alpha
10+
workflow_dispatch:
11+
12+
env:
13+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
14+
15+
permissions:
16+
contents: write
17+
18+
jobs:
19+
release:
20+
name: Release
21+
runs-on: ubuntu-latest
22+
steps:
23+
- name: Checkout
24+
uses: actions/checkout@v3
25+
with:
26+
fetch-depth: 0
27+
28+
- uses: actions/setup-go@v3
29+
with:
30+
go-version: 1.19
31+
32+
- uses: go-semantic-release/action@v1
33+
with:
34+
hooks: goreleaser
35+
env:
36+
GITHUB_TOKEN: ${{ secrets.ACTIONS_BOT_TOKEN }}

‎Dockerfile‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
FROM golang:1.20-alpine as builder
2+
3+
ENV CGO_ENABLED 0
4+
ENV GO111MODULE=on
5+
6+
WORKDIR /app
7+
8+
RUN apk update --no-cache && apk add --no-cache tzdata
9+
10+
COPY . ./
11+
12+
RUN go mod download
13+
14+
RUN go build -o main .
15+
16+
FROM alpine
17+
18+
WORKDIR /app
19+
20+
COPY --from=builder /usr/share/zoneinfo/Asia/Shanghai /usr/share/zoneinfo/Asia/Shanghai
21+
COPY --from=builder /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
22+
COPY --from=builder /app/main /app/main
23+
24+
RUN apk update --no-cache && apk add --no-cache ca-certificates
25+
RUN set -ex; \
26+
apk add --no-cache supervisor && \
27+
echo "Asia/Shanghai" > /etc/timezone && \
28+
rm -rf /var/cache/apk/*
29+
30+
EXPOSE 8080
31+
ENTRYPOINT ["/app/main"]

‎go.mod‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module proxy
2+
3+
go 1.20

‎main.go‎

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package main
2+
3+
import (
4+
"net/http"
5+
"net/http/httputil"
6+
"net/url"
7+
)
8+
9+
func main() {
10+
http.HandleFunc("/ping", func(w http.ResponseWriter, r *http.Request) {
11+
_, err := w.Write([]byte("pong"))
12+
if err != nil {
13+
return
14+
}
15+
})
16+
17+
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
18+
targetUrl := "https://api.openai.com"
19+
target, err := url.Parse(targetUrl)
20+
if err != nil {
21+
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
22+
return
23+
}
24+
r.Header.Set("Authorization", r.Header.Get("Authorization"))
25+
r.Header.Set("Content-Type", "application/json")
26+
r.Host = r.URL.Host
27+
28+
proxy := httputil.NewSingleHostReverseProxy(target)
29+
30+
if r.Header.Get("Accept") == "text/event-stream" {
31+
handleSSE(w, r, proxy)
32+
} else {
33+
proxy.ServeHTTP(w, r)
34+
}
35+
})
36+
37+
err := http.ListenAndServe(":8080", nil)
38+
if err != nil {
39+
return
40+
}
41+
}
42+
43+
func handleSSE(w http.ResponseWriter, r *http.Request, proxy *httputil.ReverseProxy) {
44+
w.Header().Set("Content-Type", "text/event-stream")
45+
w.Header().Set("Cache-Control", "no-cache")
46+
w.Header().Set("Connection", "keep-alive")
47+
48+
proxy.Transport = &http.Transport{
49+
Proxy: http.ProxyFromEnvironment,
50+
}
51+
// Start proxying SSE request to OpenAI API
52+
done := make(chan bool)
53+
go func() {
54+
proxy.ServeHTTP(w, r)
55+
done <- true
56+
}()
57+
58+
// Wait for SSE request to finish
59+
<-done
60+
}

0 commit comments

Comments
 (0)