Golang重写HTTP请求体

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

Golang rewrite http request body

问题

我正在服务器端使用Golang编写一个HTTP拦截器。我可以从r.Body中读取HTTP请求体。现在,如果我想修改请求体内容,在控制权传递给下一个拦截器之前,我该如何修改请求体?

func(w http.ResponseWriter, r *http.Request) {
    // 现在我想修改请求体,并处理(w, r)
}
英文:

I'm writing an http interceptor in Golang on the server side. I can read the http request body from r.Body. Now If I want to modify the body content, how can I modify the request body before the control is passed to the next interceptor?

func(w http.ResponseWriter, r *http.Request) {
	// Now I want to modify the request body, and 
    // handle(w, r)
}

答案1

得分: 22

Body io.ReadCloser

似乎唯一的方法是用适合 io.ReadCloser 接口的对象替换 Body。为此,您需要使用返回 io.Reader 对象的任何函数构造一个 Body 对象,并使用 ioutil.NopCloserio.Reader 对象转换为 io.ReadCloser

bytes.NewBufferString

> NewBufferString 使用字符串 s 初始化并创建一个新的缓冲区。它用于准备一个缓冲区以读取现有字符串。

strings.NewReader (在下面的示例中使用)

> NewReader 返回一个从字符串 s 读取的新 Reader。它类似于 bytes.NewBufferString,但更高效且只读。

ioutil.NopCloser

> NopCloser 返回一个使用提供的 Reader r 包装的无操作 Close 方法的 ReadCloser。

new_body_content := "新内容。"
r.Body = ioutil.NopCloser(strings.NewReader(new_body_content))

相关属性

但为了清晰明了,不要混淆应用程序的其他部分,您需要更改与 Body 内容相关的 Request 属性。大多数情况下,只需更改 ContentLength

r.ContentLength = int64(len(new_body_content))

在极少数情况下,如果您的新内容使用与原始 Body 不同的编码方式,可能还需要更改 TransferEncoding

英文:

Body io.ReadCloser

It seems like the only way is to substitute a Body with an object appropriate to io.ReadCloser interface. For this purpose you need to construct a Body object using any function which returns io.Reader object and ioutil.NopCloser to turn the io.Reader object to io.ReadCloser.

bytes.NewBufferString

> NewBufferString creates and initializes a new Buffer using string s as its initial contents. It is intended to prepare a buffer to read an existing string.

strings.NewReader (used in an example below)

> NewReader returns a new Reader reading from s. It is similar to bytes.NewBufferString but more efficient and read-only.

ioutil.NopCloser

> NopCloser returns a ReadCloser with a no-op Close method wrapping the provided Reader r.

new_body_content := "New content."
r.Body = ioutil.NopCloser(strings.NewReader(new_body_content))

But to be clear and not to confuse other parts of the application you need to change Request attributes related to Body content. Most of the time it is only ContentLength:

r.ContentLength = int64(len(new_body_content))

And in a rare case, when your new content uses different encodings from original Body, it could be TransferEncoding.

huangapple
  • 本文由 发表于 2015年11月9日 17:46:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/33606330.html
匿名

发表评论

匿名网友

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

确定