我在这里原来的问题被标记为该问题的重复。我没有实现它的运气,并且怀疑我的问题被误解了,所以在我的问题结束时,我从一个更具体的问题开始着手。
我正在尝试基于中间代理中响应代理的响应标头设置cookie,该请求被反向代理。
这是工作流程:
X-FOO
MYAPPFOO
带有X-FOO
响应标头值的cookie来修改响应有人建议,可以使用自定义http.ResponseWriter
方式,但是在尝试并搜索更多信息后,尚不清楚如何实现此目的。
由于我无法掌握用例的自定义ResponseWriter的概念,因此我将发布代码,以更精确地演示我在遇到困难时试图做的事情:
package main
import (
"github.com/gorilla/mux"
"log"
"net/http"
"net/http/httputil"
"net/url"
)
func setCookie(w http.ResponseWriter, name string, value string) {
...
http.SetCookie(w, &cookie)
}
func handler(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// setCookie() works here
// but I cannot access w.Header().Get("X-FOO")
next.ServeHTTP(w, r)
// I can access w.Header().Get("X-FOO") here
// but setCookie() does not cookie the user's browser
// If I could do it all in one place, this is what I would do:
if r.Method == "POST" && r.URL.String() == "/login" {
foo := w.Header().Get("X-FOO")
setCookie(w, "MYAPPFOO", foo)
}
})
}
func main() {
r := mux.NewRouter()
r.Use(handler)
proxy := httputil.NewSingleHostReverseProxy("https://baz.example.com/")
r.PathPrefix("/").Handler(proxy)
log.Fatal(http.ListenAndServe(":9001", r))
}
附带说明一下,我能够按照ReverseProxy.ModifyResponse
上一个问题的注释中的建议进行这项工作,但我真的很想用中间件来实现这一点,以保持从配置中动态创建代理的代码干净。(不在示例代码中)
从有关http.ResponseWriter
方法的文档中:(
添加了重点)
Header() http.Header
:除非修改后的标头是预告片,否则在 调用WriteHeader(或Write)后 更改标头映射 无效 。
WriteHeader(statusCode int)
:WriteHeader 发送 带有提供的状态代码 的HTTP响应标头 。
Write([]byte) (int, error)
:如果尚未 调用WriteHeader ,则Write 在写入数据之前会 调用WriteHeader(http.StatusOK) 。
这应该强调为什么,你不能设置在后一个cookie的原因next.ServeHTTP(w, r)
调用,这是在通过电话执行的中间件链中的处理程序中的一个或者打电话WriteHeader
或Write
直接或间接的。
因此,要能够在调用 之后 设置cookie ,next.ServeHTTP(w, r)
您需要确保中间件链调用WriteHeader
或Write
原始http.ResponseWriter
实例中没有任何处理程序。一种方法是将原始实例包装在自定义http.ResponseWriter
实现中,该实现将
推迟 响应的编写,直到完成cookie设置为止。
例如这样的事情:
type responsewriter struct {
w http.ResponseWriter
buf bytes.Buffer
code int
}
func (rw *responsewriter) Header() http.Header {
return rw.w.Header()
}
func (rw *responsewriter) WriteHeader(statusCode int) {
rw.code = statusCode
}
func (rw *responsewriter) Write(data []byte) (int, error) {
return rw.buf.Write(data)
}
func (rw *responsewriter) Done() (int64, error) {
if rw.code > 0 {
rw.w.WriteHeader(rw.code)
}
return io.Copy(rw.w, &rw.buf)
}
您可以在中间件中像这样使用它:
func handler(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
rw := &responsewriter{w: w}
next.ServeHTTP(rw, r)
if r.Method == "POST" && r.URL.String() == "/login" {
foo := rw.Header().Get("X-FOO")
setCookie(rw, "MYAPPFOO", foo)
}
if _, err := rw.Done(); err != nil {
log.Println(err)
}
})
}
我通过endpoint与我的laravel服务器通话。我不使用Laravel View,因此无法访问其会话。 当一个需要的请求进来,我需要返回一个响应即etc每个参数?可能吗? 内部: 如果我应该使用字符串消息,而不是laravel重定向没有响应,我使用邮递员,我看到状态200。如何实现我想要的?我想用响应自定义每个必需的参数。
我是Scala的新手。 我在用加特林做压力测试。 我能够进行一个Gatling测试,向WS发出请求,我将JSON响应保存在session变量中。响应是一个JSON数组,其中包含指向我的后端提供的图像的多个链接。 具体来说,第一个请求检索地图中的点,每个点都分配了一个图像,必须通过访问第一个WS响应提供的链接来获取每个图像。 我有以下代码: 第一个WS的JSON响应示例: 第一个请求工作正常,我不使
问题内容: 我需要在cfml页面中使用自己的java类。 文档中的此项听起来不错,但没有说明我必须创建哪些文件。 我试图在网站根目录下创建一个页面。然后将+ 放在同一路径中。但这会导致错误“找不到类”! 你能帮我么? 问题答案: 同一路径中的TestClass.java + TestClass.class。 您不能仅将文件放置在任何地方。CF服务器启动时, 仅 检查类/ jar的特定位置。这些位置
我有一个实现REST API的spring boot应用程序。我有一个POSTendpoint,它通过接收一个对象,这个对象有几个字段,其中一些字段的类型为。我面临的问题是,当我接收到一个包含字母字符串作为long类型字段值的无效请求有效负载时,应用程序返回一个带有空有效负载的HTTP 400响应,但我希望能够自定义该响应(例如通过)并提供一些错误描述。然而,直到现在我都没能做到。 请求有效负载对
我已经开发了一个Java web应用程序,我想实现SAML。我认为这些是实现SAML的正确步骤。 服务提供商(SP,在本例中是我的应用程序)向IdP发送SAML身份验证请求 然后,IdP对其进行验证,创建SAML响应断言,并将其与证书一起签名,然后发送回SP。 然后,SP使用密钥库中证书的公钥对其进行验证,并在此基础上进一步进行 我有一个示例代码,可以创建SAML请求 我可以对其进行编码并发送给I
我正在尝试从JavaScript应用程序向另一个应用程序中的endpoint进行API调用。 当我调用endpoint时,我得到了状态代码和消息,但我无法以任何方式访问响应体。我已经尝试了不同的方法来获取数据,但似乎没有一种方法对我有效。 在方法“someAction”中,我想使用来自API调用的响应/结果中的数据。我在代码中添加了单个日志行打印的输出。 如何在定义“result.status/m