# 利用Golang反代某AI的API

某AI的API在部分地区不太稳定，这里可以在稳定的地区进行反代。

## 反代用的Golang源码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104

    package main

    import (
    "log"
    "net/http"
    "net/http/httputil"
    "net/url"
    "strings"
    )

    type RProxy struct {
    remote *url.URL
    }

    func GoReverseProxy(this *RProxy) *httputil.ReverseProxy {
    remote := this.remote

    proxy := httputil.NewSingleHostReverseProxy(remote)

    proxy.Director = func(request *http.Request) {
    targetQuery := remote.RawQuery
    request.URL.Scheme = remote.Scheme
    request.URL.Host = remote.Host
    request.Host = remote.Host // todo 这个是关键
    request.URL.Path, request.URL.RawPath = joinURLPath(remote, request.URL)

    if targetQuery == ""  request.URL.RawQuery == "" {
    request.URL.RawQuery = targetQuery + request.URL.RawQuery
    } else {
    request.URL.RawQuery = targetQuery + "&" + request.URL.RawQuery
    }
    if _, ok := request.Header["User-Agent"]; !ok {
    // explicitly disable User-Agent so it's not set to default value
    request.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36")
    }
    log.Println("request.URL.Path：", request.URL.Path, "request.URL.RawQuery：", request.URL.RawQuery)
    }

    // 修改响应头
    proxy.ModifyResponse = func(response *http.Response) error {
    response.Header.Add("Access-Control-Allow-Origin", "*")
    response.Header.Add("Reverse-Proxy-Server-PowerBy", "(Hzz)https://hzz.cool")
    return nil
    }

    return proxy
    }

    // go sdk 源码
    func joinURLPath(a, b *url.URL) (path, rawpath string) {
    if a.RawPath == "" && b.RawPath == "" {
    return singleJoiningSlash(a.Path, b.Path), ""
    }
    // Same as singleJoiningSlash, but uses EscapedPath to determine
    // whether a slash should be added
    apath := a.EscapedPath()
    bpath := b.EscapedPath()

    aslash := strings.HasSuffix(apath, "/")
    bslash := strings.HasPrefix(bpath, "/")

    switch {
    case aslash && bslash:
    return a.Path + b.Path[1:], apath + bpath[1:]
    case !aslash && !bslash:
    return a.Path + "/" + b.Path, apath + "/" + bpath
    }
    return a.Path + b.Path, apath + bpath
    }

    // go sdk 源码
    func singleJoiningSlash(a, b string) string {
    aslash := strings.HasSuffix(a, "/")
    bslash := strings.HasPrefix(b, "/")
    switch {
    case aslash && bslash:
    return a + b[1:]
    case !aslash && !bslash:
    return a + "/" + b
    }
    return a + b
    }

    func main() {
    port := "1874"
    reverseUrl := "https://api.openai.com"

    remote, err := url.Parse(reverseUrl)
    if err != nil {
    panic(err)
    }

    proxy := GoReverseProxy(&RProxy{
    remote: remote,
    })

    log.Println("当前代理地址： " + reverseUrl + " 本地监听： http://127.0.0.1:" + port)

    serveErr := http.ListenAndServe(":"+port, proxy)

    if serveErr != nil {
    panic(serveErr)
    }
    }

## 编译Golang源码

- 尝试用Golang静态编译可执行文件
- CC=musl-gcc /home/jovyan/go/bin/go1.20.1 build -tags musl -o openai -trimpath -ldflags ‘-linkmode “external” -extldflags “-static” -s -w -buildid=’ ./openai.go

## 编写Dockerfile

    1
    2
    3
    4
    5
    6
    7
    8

    # set alpine as the base image of the Dockerfile
    FROM alpine:latest

    # Copy over the torrc created above and set the owner to `tor`
    COPY openai /bin/openai

    # Set `tor` as the entrypoint for the image
    ENTRYPOINT ["/bin/openai"]

- mkdir -p ~/app/openai && cd ~/app/openai && nano Dockerfile && nano docker-compose.yml
- 上传编译好的openai可执行文件
- chmod +x openai
- docker build -t limour/openai .

## 部署Docker并反代

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    version: '3.3'
    services:
        openai:
            container_name: openai
            restart: always
            image: limour/openai

    networks:
      default:
        external: true
        name: ngpm

- Nginx Proxy Manager进阶：使用Docker network
- sudo docker-compose up -d && sudo docker-compose logs
- 然后在Nginx Proxy Manager中反代openai:1874

开源
利用Golang反代某AI的API
https://occdn.limour.top/2607.html
Author
Limour
Posted on
March 3, 2023
Licensed under
利用API部署自己的AGI Previous
SOCKS5转QUIC Next

#### Search

Keyword