去http请求重定向

Go http request redirect

我正在写一个 API 必须将传入请求重定向到另一个服务,响应必须转发给原始请求者。

我认为像下面这样的简单函数应该可以解决问题,但我错了。

我从重定向的响应中收到数据,但是当我将其发送回初始请求时,我收到的响应没有任何数据 Could not get response. Error: socket hang up

如果我尝试使用邮递员直接执行相同的请求到重定向 URL 它工作得很好。

func initialAssetsHandler(w http.ResponseWriter, r *http.Request) {
    body, err := ioutil.ReadAll(r.Body)
    if err != nil {
        fmt.Println(err)
        return
    }

    resp, err := http.Post(conf.redirectURL, "application/json", bytes.NewReader(body))
    if err != nil {
        log.Error(err)
    }
    defer resp.Body.Close()
    buf := new(bytes.Buffer)
    buf.ReadFrom(resp.Body)
    log.Info(string(buf.Bytes()))

    var data json.RawMessage
    if err = json.NewDecoder(resp.Body).Decode(&data); err != nil {
        fmt.Println(err)
        return
    }
    helper.SendJsonRaw(w, 200, data)
}

这是 SendJsonRaw 函数:

func SendJsonRaw(w http.ResponseWriter, status int, r json.RawMessage) error {
    w.Header().Set(HeaderContentType, MimeApplicationJSON)
    w.WriteHeader(status)
    _, err := w.Write(r)
    return err
}

r.Body 被 json 解码器读取到 EOF,然后当您将它传递给重定向请求时,它看起来 到 http.Client,因此它不发送正文。您需要保留正文的内容。

例如,您可以执行以下操作:

func initialAssetsHandler(w http.ResponseWriter, r *http.Request) {
    body, err := ioutil.ReadAll(r.Body)
    if err != nil {
        fmt.Println(err)
        return
    }

    var initialAssets TagAssets
    if err := json.Unmarshal(&initialAssets, body); err != nil {
        if !strings.Contains(err.Error(), "json: invalid use of ,string struct tag, trying to unmarshal") {
            helper.SendJsonError(w, http.StatusBadRequest, err)
            return
        }
    }

    resp, err := http.Post(conf.redirectURL, "application/json", bytes.NewReader(body))
    if err != nil {
        log.Error(err)
    }
    defer resp.Body.Close()
    log.Info(resp)

    var data json.RawMessage
    if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
        fmt.Println(err)
        return
    }
    helper.SendJsonOk(w, data)
}