当前位置: 首页 > 面试题库 >

在不修改请求状态的情况下读取http.Request的正文?

盖和洽
2023-03-14
问题内容

我有一个实现http.Handler接口的类型,该接口在其ServeHTTP方法中检查传入的HTTP请求,采取某些措施,然后将请求转发到反向代理处理程序(httputil.NewSingleHostReverseProxy)。

只要我仅检查基本的请求属性(例如URL或标头),此方法就可以正常工作。

当我想检查传入的POST请求的主体(例如,通过调用req.ParseForm()然后使用req.Form属性)时,将请求传递到反向代理后,就会遇到错误:

http: proxy error: http: Request.ContentLength=687 with Body length 0

我认为发生这种情况是因为查看HTTP请求的正文会导致req.Body.Reader流被耗尽,这意味着代理处理程序无法再次读取它。

我一直在玩诸如io.Copy()和这类的东西bufio.Peek(),但是我什么都没有。

有没有一种方法可以窥视HTTP请求主体(并使用内置的解析req.ParseForm等),同时将原始请求对象保留为原始状态,以便可以将其传递给反向代理?


问题答案:

尝试读入缓冲区,然后使用缓冲区支持两个新的读取器,一个供您使用,另一个供以后的使用者使用。例如,假设我们要修改以下代码

doStuff(r.Body) // r is an http.Request

我们可以做:

buf, _ := ioutil.ReadAll(r.Body)
rdr1 := ioutil.NopCloser(bytes.NewBuffer(buf))
rdr2 := ioutil.NopCloser(bytes.NewBuffer(buf))

doStuff(rdr1)
r.Body = rdr2 // OK since rdr2 implements the io.ReadCloser interface

// Now the program can continue oblivious to the fact that
// r.Body was ever touched.

请注意,*bytes.Buffer它没有Close() error方法,因此没有实现io.ReadCloser接口。因此,我们必须将*bytes.Buffer值包装在对的调用中ioutil.NopCloser



 类似资料:
  • 我有一个实现接口,在其方法中,检查传入的HTTP请求,采取一些操作,然后将请求转发到反向代理处理程序()。 只要我只检查基本请求属性(如URL或标头),就可以正常工作。 当我想检查传入POST请求的主体时,例如通过调用然后使用属性,一旦请求传递到反向代理,我就会遇到错误: 我认为这是因为查看HTTP请求的主体会导致要排空的流,这意味着代理处理程序无法再次读取该流。 我一直在玩和,但我真的没有什么进

  • 我正在基于Tomcat servlet和NIO创建服务。输入时有大的XML请求(约100 MB),通过HTML POST方法发送。我只想流前8千磅,然后立即发送响应到客户端。 当我尝试发送小请求(内容中只有几行)时,套接字工作正常。 2016-02-01 10:44:52 Http11NioProtocol[DEBUG]套接字:[org.apache.tomcat.util.net.NioEndp

  • 我刚刚意识到,在Lollipop下面的Android版本上,不可能通过appcompat改变状态栏的颜色。我目前正在运行Android Kitkat 4.4.2,并收到了一个应用程序的更新,以下是截图 我的问题是,他们是如何在运行比Lollipop低版本的设备上不使用appcompat而改变状态栏颜色的? 怎么可能改变颜色?

  • (Java版本8) 我需要在过滤器中处理请求正文。使用下面的代码,我读取了正文。 问题是如果请求正文发布的参数的内容类型为“Application/x-www-form-urlencoded”,那么这些参数在读取正文后将不可用。如果我不读取正文,它们可以使用request.getParameter()获取。 此外,我尝试使用以下代码包装请求并提供正文,这样解决方案的其余部分(例如servlet)就

  • null 但是,当与HTTP1建立连接时,最后调用。 http1ExchangeCodeC.FixedLengthSource::Close 然后,方法读取所有响应体源,如下所示。