Go http request redirect

huangapple go评论73阅读模式
英文:

Go http request redirect

问题

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

我想到了下面这样一个简单的函数应该可以解决问题,但我错了。

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

如果我尝试直接使用Postman执行完全相同的请求到重定向的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
}
英文:

I am writing an API whichs has to redirect incoming requests to another service, the response must be forwarded to the original requester.

I figured a simple function like below should do the trick, but I was wrong.

I receive the data from my redirected response, however when I send it back to the initial request I receive this response without any data Could not get response. Error: socket hang up

If I try to execute the very same request using postman straight to the redirect URL it works perfectly fine.

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)
}

Here is the SendJsonRaw function:

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
}

答案1

得分: 1

r.Body被json解码器读取直到EOF,然后当你将其传递给重定向请求时,对于http.Client来说它看起来是空的,因此它不发送任何body。你需要保留body的内容。

例如,你可以这样做:

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)
}
英文:

The r.Body is read by the json decoder up to EOF, then when you pass it to the redirect request it looks empty to the http.Client and therefore it sends no body. You need to retain the content of the body.

For example you can do the following:

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)
}

huangapple
  • 本文由 发表于 2021年7月25日 21:17:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/68518928.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定