如何增强 ResponseWriter 的 Header() 返回的地图

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

How to augment the map returned by a ResponseWriter's Header()

问题

我确定我在这里尝试作弊,但是ResponseWriter文档中有一个名为'Header()'的方法,它返回它正在使用的Header对象。
https://pkg.go.dev/net/http#ResponseWriter.Header

现在我从其他地方获取了一个http.Response,并且我想将该响应的所有标头复制到我的ResponseWriter中。

现在,我可以使用类似这样的for循环:

for k := range resp.Header 
    w.Header().Add(k, resp.Header.Get(k))
}

从逻辑上讲,我也认为只需将ResponseWriter的header引用更改为Response的header即可,但是似乎ResponseWriter类型正在积极阻止我这样做。

脑海中浮现出一些愚蠢的想法

w.Header() = resp.Header

或者

rwHeader := w.Header()
rwHeader = resp.Header

显然,这两种方法都没有意义,根本不起作用,但希望能传达我尝试做的事情的想法。

有人能解释一下为什么我尝试的方法不起作用吗?或者也许它确实起作用,只是我没有找到方法?

英文:

So I'm sure I'm trying to cheat here, but the ResponseWriter docs has a method 'Header()' which returns the Header object it's using.
https://pkg.go.dev/net/http#ResponseWriter.Header

Now I'm getting a http.Response from somewhere else, and I want to copy across all the headers from that into my ResponseWriter.

Now, I could use a for loop like this:

for k := range resp.Header 
    w.Header().Add(k, resp.Header.Get(k))
}

Logically, it also made sense for me to just change the reference from the ResponseWriter's header, to the Response's header, however it seems like the ResponseWriter type is actively trying to stop me from doing that.

Something stupid like this comes to mind

w.Header() = resp.Header

Or

rwHeader := w.Header()
rwHeader = resp.Header

Obviously both of these make no sense and do not work at all, but hopefully conveys the idea of what I'm trying to do.

Can anyone offer an explanation of why what I'm trying to do doesn't work? Or maybe it does and I'm just not seeing the way to do it?

答案1

得分: 3

你不需要自己编写那个循环。Go 1.18 中引入了 golang.org/x/exp/maps 包,它提供了一个方便的 Copy 函数

func Copy[M ~map[K]V, K comparable, V any](dst, src M)

Copy 函数将 src 中的所有键值对复制并添加到 dst 中。当 src 中的键在 dst 中已经存在时,dst 中的值将被 src 中的键关联的值覆盖。

import "golang.org/x/exp/maps"
// ...
maps.Copy(w.Header(), resp.Header)

然而,请注意,由于响应可以包含重复的头部,使用 maps.Copy 并不完全等同于你的循环:

for k := range resp.Header 
    w.Header().Add(k, resp.Header.Get(k))
}

maps.Copy 不同,你的循环只检索与 resp.Header 中每个头部名称对应的第一个头部值。

英文:

You don't have to write that loop yourself. Go 1.18 saw the addition of package golang.org/x/exp/maps, which provides a convenient Copy function:

> go
> func Copy[M ~map[K]V, K comparable, V any](dst, src M)
>

>
> Copy copies all key/value pairs in src adding them to dst. When
> a key in src is already present in dst, the value in dst will be
> overwritten by the value associated with the key in src.

import "golang.org/x/exp/maps"
// ...
maps.Copy(w.Header(), resp.Header)

However, note that, because a response can contain duplicate headers, the use of maps.Copy isn't exactly equivalent to your loop:

for k := range resp.Header 
    w.Header().Add(k, resp.Header.Get(k))
}

Contrary to maps.Copy, your loop retrieves only the first header value corresponding to each header name present in resp.Header.

答案2

得分: 2

你不能这样做。

w 是一个 http.ResponseWriter,它是一个接口类型,只有方法而没有直接可访问的字段。它有一个方法可以获取底层的 Header 映射。

然而,它没有一个“Setter”方法来替换映射。所以唯一的方法是手动复制头部值,就像你引用的循环所做的那样。

英文:

You can't.

w is an http.ResponseWriter which is an interface type - so only has methods and no directly accessible fields. It has, as you know, a method to get the underlying Header map.

It does not, however, have a "Setter" method to replace the map. So the only way to copy over header values is by hand like your cited loop does.

huangapple
  • 本文由 发表于 2022年4月12日 21:22:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/71843507.html
匿名

发表评论

匿名网友

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

确定