package main
import (
"bytes"
"encoding/json"
"io/ioutil"
"log"
"net/http"
"net/http/httputil"
"net/url"
)
const PORT = "1330"
const A_CONDITION_URL = "http://localhost:1331"
const B_CONDITION_URL = "http://localhost:1332"
const DEFAULT_CONDITION_URL = "http://localhost:1333"
type requestPayloadStruct struct {
ProxyCondition string `json:"proxy_condition"`
}
func getListenAddress() string {
return ":" + PORT
}
func logSetup() {
log.Printf("Server will run on: %s\n", getListenAddress())
log.Printf("Redirecting to A url: %s\n", A_CONDITION_URL)
log.Printf("Redirecting to B url: %s\n", B_CONDITION_URL)
log.Printf("Redirecting to Default url: %s\n", DEFAULT_CONDITION_URL)
}
func requestBodyDecoder(request *http.Request) *json.Decoder {
body, err := ioutil.ReadAll(request.Body)
if err != nil {
log.Printf("Error reading body: %v", err)
panic(err)
}
request.Body = ioutil.NopCloser(bytes.NewBuffer(body))
return json.NewDecoder(ioutil.NopCloser(bytes.NewBuffer(body)))
}
func parseRequestBody(request *http.Request) requestPayloadStruct {
decoder := requestBodyDecoder(request)
var requestPayload requestPayloadStruct
err := decoder.Decode(&requestPayload)
if err != nil {
panic(err)
}
return requestPayload
}
func getProxyUrl(proxyConditionRaw string) string {
proxyCondition := strings.ToUpper(proxyConditionRaw)
if proxyCondition == "A" {
return A_CONDITION_URL
}
if proxyCondition == "B" {
return B_CONDITION_URL
}
return DEFAULT_CONDITION_URL
}
func serveReverseProxy(target *url.URL, response http.ResponseWriter, request *http.Request) {
proxy := httputil.NewSingleHostReverseProxy(target)
proxy.ServeHTTP(response, request)
}
func handleRequestAndRedirect(response http.ResponseWriter, request *http.Request) {
requestPayload := parseRequestBody(request)
url := getProxyUrl(requestPayload.ProxyCondition)
target, _ := url.Parse(url)
serveReverseProxy(target, response, request)
}
func main() {
logSetup()
http.HandleFunc("/", handleRequestAndRedirect)
if err := http.ListenAndServe(getListenAddress(), nil); err != nil {
panic(err)
}
}
在这个例子中,我们首先定义了一些常量和请求体的结构。logSetup
函数用于打印日志信息。requestBodyDecoder
和parseRequestBody
函数用于解析请求体中的JSON数据。getProxyUrl
函数根据请求体中的条件返回相应的代理URL。serveReverseProxy
函数创建一个反向代理并处理HTTP请求。
要运行这个代理服务器,你可以将代码保存到main.go
文件中,然后使用go run main.go
命令启动服务器。服务器将监听指定的端口,并根据请求体中的内容将请求转发到不同的后端服务。