英文:
How do I set multi-value HTTP headers, like Content-Security-Policy?
问题
我正在尝试在http.ResponseWriter对象上设置Content-Security-Policy头。这是一个具有多个值的头部。我的问题是,http.Header的所有方法都需要一个键和一个值。例如,Set()方法的形式如下:
func (h Header) Set(key, value string)
没有一种方法可以将值的切片分配给头字段。我想要一个看起来像这样的头部。
header := http.Header{
"Content-Type": {"text/html; charset=UTF-8"},
"Content-Security-Policy": {"default-src 'self'", "font-src themes.googleusercontent.com", "frame-src 'none'", "style-src 'self' fonts.googleapis.com"},
}
这将创建头部,但我不知道如何将其与http.ResponseWriter对象关联起来。此外,如果我以某种方式能够用上述头部替换ResponseWriter的头部,我是否需要手动设置Content-Length字段?
英文:
I'm trying to set the Content-Security-Policy header on a http.ResponseWriter object. This is a header with multiple values. My problem is that all the methods for http.Header take a single key and a single value. For example, the Set() method looks like this:
func (h Header) Set(key, value string)
There's no method for assigning a slice of values to a header field. I want a header that looks like this.
header := http.Header{
"Content-Type": {"text/html; charset=UTF-8"},
"Content-Security-Policy": {"default-src 'self'", "font-src themes.googleusercontent.com", "frame-src 'none'", "style-src 'self' fonts.googleapis.com"},
}
This will create the header, but I don't know how to associate it with the http.ResponseWriter object. Furthermore, if I were somehow able to replace the ResponseWriter's header with the header above, would I have to set the Content-Length field by hand?
答案1
得分: 4
我不确定我完全理解这个问题,但是Content-Security-Policy
期望一个包含由;
分隔的列表的头部。
如果你想使用一个切片,你可以像这样使用:
csp := []string{"default-src: 'self'", "font-src: 'fonts.googleapis.com'", "frame-src: 'none'"}
header := http.Header{
"Content-Type": {"text/html; charset=UTF-8"},
}
header.Set("Content-Security-Policy", strings.Join(csp, "; "))
如果你想多次发送具有不同值的头部(就像你最初打算的那样),你可以使用[`header.Add`](http://golang.org/pkg/net/http/#Header.Add)。
> Add将键值对添加到头部。**它会追加**到与键关联的任何现有值。
如果你想在你的http处理程序中使用它,可以使用[ResponseWriter.Header()](http://golang.org/pkg/net/http/#ResponseWriter)获取头部:
```go
func Handler(rw http.ResponseWriter, req *http.Request) {
header := rw.Header()
csp := []string{"default-src: 'self'", "font-src: 'fonts.googleapis.com'", "frame-src: 'none'"}
header.Set("Content-Type", "text/html; charset=UTF-8")
header.Set("Content-Security-Policy", strings.Join(csp, "; "))
rw.WriteHeader(200) //or write anything really
}
英文:
I'm not sure I fully understand the problem, however Content-Security-Policy
expects one header that contains a list separated by ;
.
If you want to use a slice you can always use something like this:
csp := []string{"default-src: 'self'", "font-src: 'fonts.googleapis.com'", "frame-src: 'none'"}
header := http.Header{
"Content-Type": {"text/html; charset=UTF-8"},
}
header.Set("Content-Security-Policy", strings.Join(csp, "; "))
Also if you want to send the header multiple times with different values (like you originally intended, I think), you can use header.Add
.
>Add adds the key, value pair to the header. It appends to any existing values associated with key.
If you want to use that in your http handler, get the header with ResponseWriter.Header():
func Handler(rw http.ResponseWriter, req *http.Request) {
header := rw.Header()
csp := []string{"default-src: 'self'", "font-src: 'fonts.googleapis.com'", "frame-src: 'none'"}
header.Set("Content-Type": "text/html; charset=UTF-8")
header.Set("Content-Security-Policy", strings.Join(csp, "; "))
rw.WriteHeader(200) //or write anything really
}
答案2
得分: 1
这个链接是关于"the other 4"安全头部的,虽然没有直接涉及到CSP,但是可以参考一下。
英文:
This doesn't address CSP directly (yet), but it does cover "the other 4" security headers
答案3
得分: 0
我创建了一个中间件来设置CSP头部。
package main
import (
"gorila-mux/ctrls"
"log"
"net/http"
"github.com/gorilla/context"
"github.com/gorilla/mux"
)
func main() {
r := mux.NewRouter()
r.HandleFunc("/", ctrls.HomeHandler)
r.PathPrefix("/public/").Handler(http.StripPrefix("/public/", http.FileServer(http.Dir("public/"))))
http.Handle("/", r)
r.Use(setCSPHeaders)
log.Print("Project is serving on port 7000 : http://localhost:7000")
http.ListenAndServe(":7000", context.ClearHandler(http.DefaultServeMux))
}
func setCSPHeaders(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.Header().Set("Content-Security-Policy", "default-src 'self'; script-src 'self'; object-src 'self';style-src 'self' img-src 'self'; media-src 'self'; frame-ancestors 'self'; frame-src 'self'; connect-src 'self'")
next.ServeHTTP(w, r)
})
}
以上是要翻译的内容。
英文:
I created a middleware to set the CSP header.
package main
import (
"gorila-mux/ctrls"
"log"
"net/http"
"github.com/gorilla/context"
"github.com/gorilla/mux"
)
func main() {
r := mux.NewRouter()
r.HandleFunc("/", ctrls.HomeHandler)
r.PathPrefix("/public/").Handler(http.StripPrefix("/public/", http.FileServer(http.Dir("public/"))))
http.Handle("/", r)
r.Use(setCSPHeaders)
log.Print("Project is serving on port 7000 : http://localhost:7000")
http.ListenAndServe(":7000", context.ClearHandler(http.DefaultServeMux))
}
func setCSPHeaders(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.Header().Set("Content-Security-Policy", "default-src 'self'; script-src 'self'; object-src 'self';style-src 'self' img-src 'self'; media-src 'self'; frame-ancestors 'self'; frame-src 'self'; connect-src 'self'")
next.ServeHTTP(w, r)
})
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论