diff --git a/README.md b/README.md index b680452..4be9cbf 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,15 @@ # openapi-scf-proxy-go This repository is inspired by [Ice-Hazymoon/openai-scf-proxy](https://github.com/Ice-Hazymoon/openai-scf-proxy). + +## 腾讯云函数SCF服务的设置 +添加环境变量: +* ProxyHostURL=https://api.openai.com +* ProxyListenOn=0.0.0.0:9000 + +编译压缩命令: +```shell +GOOS=linux GOARCH=amd64 go build -o main main.go +zip main.zip main scf_bootstrap +``` + +函数服务部署成功后,通过APIGW访问。 diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..dfae351 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module openapi-scf-proxy-go + +go 1.19 diff --git a/main.go b/main.go new file mode 100644 index 0000000..8f1098d --- /dev/null +++ b/main.go @@ -0,0 +1,37 @@ +package main + +import ( + "log" + "net/http" + "os" + + pp "openapi-scf-proxy-go/proxy" +) + +var ( + Target string + ListenOn string +) + +func init() { + // TargetHostURL=https://api.openai.com + Target = os.Getenv("ProxyHostURL") + // ProxyListenOn=0.0.0.0:9000 + ListenOn = os.Getenv("ProxyListenOn") +} + +func main() { + if len(Target) == 0 || len(ListenOn) == 0 { + panic("ProxyHostURL or ProxyListenOn is null.") + } + + // initialize a reverse proxy and pass the actual backend server url here + proxy, err := pp.New(Target) + if err != nil { + panic(err) + } + + // handle all requests to your server using the proxy + http.HandleFunc("/", pp.RequestHandler(proxy)) + log.Fatal(http.ListenAndServe(ListenOn, nil)) +} diff --git a/proxy/proxy.go b/proxy/proxy.go new file mode 100644 index 0000000..34a8824 --- /dev/null +++ b/proxy/proxy.go @@ -0,0 +1,57 @@ +package proxy + +import ( + "fmt" + "log" + "net/http" + "net/http/httputil" + "net/url" +) + +// New takes target host and creates a reverse proxy +func New(targetHost string) (*httputil.ReverseProxy, error) { + url, err := url.Parse(targetHost) + if err != nil { + return nil, err + } + + proxy := httputil.NewSingleHostReverseProxy(url) + + originalDirector := proxy.Director + proxy.Director = func(req *http.Request) { + originalDirector(req) + modifyRequest(req, url.Host) + } + + proxy.ModifyResponse = modifyResponse() + proxy.ErrorHandler = errorHandler() + return proxy, nil +} + +func modifyRequest(req *http.Request, targetHost string) { + req.Host = targetHost +} + +func errorHandler() func(http.ResponseWriter, *http.Request, error) { + return func(w http.ResponseWriter, req *http.Request, err error) { + if err != nil { + fmt.Printf("Got error while modifying response: %v \n", err) + } + return + } +} + +func modifyResponse() func(*http.Response) error { + return func(resp *http.Response) error { + resp.Header.Set("x-proxy-by", "go") + log.Println(resp.StatusCode) + return nil + } +} + +// RequestHandler handles the http request using proxy +func RequestHandler(proxy *httputil.ReverseProxy) func(http.ResponseWriter, *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { + proxy.ServeHTTP(w, r) + } +}