- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我正在尝试同时使用 gorilla mux 和 httputil.ReverseProxy,但是在尝试获取 mux.Vars 时它是空的。根据https://golang.org/src/net/http/httputil/reverseproxy.go?s=2744:2819#L93看起来 http.Request 指针是原始请求的浅拷贝,它应该仍然有效。
有什么想法吗?
https://play.golang.org/p/JpjNvEMIFB
package main
import (
"github.com/gorilla/mux"
"log"
"net/http"
"net/http/httputil"
"net/url"
)
type route struct {
match string
base string
}
var routes = []route{
// proxy http://localhost:3000/api/foo/bar => https://api.bar.com/5/foo/bar
route{match: "/api/{path}", base: "https://api.bar.com/5"},
route{match: "/sales/{path}", base: "https://sales.bar.com/3"},
}
func NewProxy(r *route) http.Handler {
director := func(req *http.Request) {
out, _ := url.Parse(r.base)
req.URL.Scheme = out.Scheme
req.URL.Host = out.Host
req.URL.Path = out.Path + "/" + mux.Vars(req)["path"] // mux Vars are empty here
}
return &httputil.ReverseProxy{Director: director}
}
func main() {
for _, route := range routes {
http.Handle(route.match, NewProxy(&route))
}
log.Println("Listening on port 8080")
http.ListenAndServe(":8080", nil)
}
最佳答案
这里有两个不同的问题。
第一个,您没有使用mux.Router
,因此gorilla/mux
没有机会预处理您的请求。换句话说,请求直接从 http
包发送到您的反向代理。这个问题有一个简单的解决方法:
r := mux.NewRouter()
for _, route := range routes {
r.Handle(route.match, NewProxy(&route))
}
http.Handle("/", r)
第二个问题比第一个更棘手。此问题与 mux
包的实现方式有关。如果您查看 mux.Vars()
实现,您会发现它使用了一个叫做 Context
的东西。一个 Context
,如 official documentation 中所述, 是存储在请求生命周期内共享的值的东西。一个简化的上下文实现将是:
type Context map[*http.Request]interface{}
func (c Context) Set(req *http.Request, v interface{}) {
c[req] = v
}
func (c Context) Get(req *http.Request) interface{} {
return c[req]
}
如您所见,给定一个 http.Request
,我们可以将值存储在上下文中。稍后我们可以使用相同的 Context
和相同的 http.Request
检索这些值。 mux
使用一个全局的 Context
来存储在路由过程中解析的变量,以便您可以使用标准的 http.request
。但是,因为 httputil.ReverseProxy
传递实际请求的副本并且 Context
按请求链接值,所以这个新的 Request
在 上下文
。
要修复它,您可以基于 httputil.ReverseProxy
实现您自己的 ReverseProxy
:
type MyReverseProxy struct {
httputil.ReverseProxy
Director func(inr, outr *http.Request)
}
func (p *MyReverseProxy) ServeHTTP(rw http.ResponseWriter, inr *http.Request) {
p.ReverseProxy.Director = func(outr *http.Request) {
p.Director(inr, outr)
}
p.ReverseProxy.ServeHTTP(rw, inr)
}
func NewProxy(r *route) http.Handler {
director := func(inr, outr *http.Request) {
out, _ := url.Parse(r.base)
outr.URL.Scheme = out.Scheme
outr.URL.Host = out.Host
outr.URL.Path = out.Path + "/" + mux.Vars(inr)["path"]
log.Printf("IN VARS: %#v\n", mux.Vars(inr)) // Now inr has proper vars
log.Printf("OUT VARS: %#v\n", mux.Vars(outr))
}
return &MyReverseProxy{Director: director}
您甚至可以使用 context
并保留 Director
声明:
type MyReverseProxy struct {
httputil.ReverseProxy
Director func(req *http.Request)
}
func (p *MyReverseProxy) ServeHTTP(rw http.ResponseWriter, inr *http.Request) {
p.ReverseProxy.Director = func(outr *http.Request) {
context.Set(outr, "in_req", inr)
p.Director(outr)
}
p.ReverseProxy.ServeHTTP(rw, inr)
}
func NewProxy(r *route) http.Handler {
director := func(outr *http.Request) {
out, _ := url.Parse(r.base)
inr := context.Get(outr, "in_req").(*http.Request)
outr.URL.Scheme = out.Scheme
outr.URL.Host = out.Host
outr.URL.Path = out.Path + "/" + mux.Vars(inr)["path"]
log.Printf("IN VARS: %#v\n", mux.Vars(inr)) // Now inr has proper vars
log.Printf("OUT VARS: %#v\n", mux.Vars(outr))
}
return &MyReverseProxy{Director: director}
}
这两种实现对我来说似乎都很棘手。他们必须在每次调用中更改 httputil.ReverseProxy
的 Director
。所以,我可能接受 mux
在这里不是一个好的选择,而是我将使用一些更简单的解决方案:
var routes = []route{
route{match: "/api/", base: "https://api.bar.com/5"},
route{match: "/sales/", base: "https://sales.bar.com/3"},
}
func NewProxy(r *route) http.Handler {
director := func(req *http.Request) {
out, _ := url.Parse(r.base)
req.URL.Scheme = out.Scheme
req.URL.Host = out.Host
req.URL.Path = out.Path + "/" + strings.TrimPrefix(req.URL.Path, r.match)
}
return &httputil.ReverseProxy{Director: director}
}
您可以阅读 mux
source code实现基于正则表达式的复杂解决方案。
关于go - mux.Vars 在使用 httputil.ReverseProxy 时为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30565518/
我正在尝试开发一个安全的 Web 应用程序,它可以接受表单数据,将其编码到数据库中以消除跨站点脚本问题,然后在其他网页上很好地格式化它。 正在使用 对表单数据进行编码 HttpUtility.Html
我尝试在 wp8.1 中开发某些应用程序时找不到 HttpUtility.UrlDecode 或 HttpUtility.UrlEncode。我包含了 System.net 命名空间。这是从 8.1
我在下载文件时遇到问题,下载时将所有空格替换为下划线。 基本上我在这里遇到了问题: Response.AddHeader("Content-Disposition", "attachment;
我正在使用这两行代码作为反向代理 reverseProxy:=httputil.NewSingleHostReverseProxy(url) reverseProxy.ServeHTTP(rw, re
我在编译 C# 应用程序时遇到此错误。看起来像是一个微不足道的错误,但我无法解决它。 我的设置是 Windows 7 64 位。 Visual-Studio 2010 C# 表示 B2Rel。 我添加
我正在尝试提取带有 + 特殊字符的电子邮件,但由于某种原因 ParseQueryString 跳过它: namespace ParsingProblem { class Pro
我必须对一个字段进行编码,以确保脚本注入(inject)的安全。 我知道我可以使用 HttpUtility.HtmlEncode 和 Decode,但是这种用于 HI-ASCII 字符的方法超出了数据
我是 Android 编程新手,我一直在学习教程以在我的应用程序中获取实时 Twitter 提要。我在我的 String twitterTweets = httpUtil.getHttpRespons
我正在尝试使用 HttpUtility.UrlEncode 对以下字符串进行编码; 1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "userbouquet.dbe01.tv" OR
我正在使用 facebook-java-api 为我的 Web 应用程序实现 facebook connect。我实际上正在遵循此 site 中的教程 我已经编写了一个 servlet 来实现教程中给
我正在尝试对要发送到网络服务进行处理的参数进行编码。我从一个带有参数的命令开始,例如: TransportProviderConfirmation/68,Akal Singh,+97254494486
当 .net 在您请求时已经解码查询字符串时,HttpUtility.UrlDecode 有什么意义。 这是经典 ASP 的后遗症还是我遗漏了什么? 最佳答案 如果您从其他来源收到 UrlEncode
我收到以下错误: The name 'HttpUtility' does not exist in the current context 我正在构建一个 winform 应用程序,这是我使用 fra
这可能是个愚蠢的问题,但每次都会让我感到困惑。 HttpUtility 有方法 HtmlDecode 和 UrlDecode。这两种方法是否解码我可能发现的任何内容(Html/Http 相关)?我什么
我有一个返回 View 的 ASP.NET MVC Controller 。在这个 View 中,我创建了一些 html。例如 @Html.ActionLink(HttpUtility.HtmlDec
我使用此代码发送彩信,所有参数都正确,但连接被拒绝。并且网络已在移动彩信上连接。 HttpUtils 是一个来自此处下载的库的类:https://github.com/android/platform
我处在一个我有一些路径的情况下。此路径可能类似于“jadajada.com/My Site.html”。 我使用 HttpUtility.UrlEncode 对 url 进行编码,这很棒。但是,我遇到
有人能给我解释一下 ParseQueryString 的这种行为吗: var qs = HttpUtility.ParseQueryString("/Site/controller/Index?dat
我试图在我的 VB.NET 项目中调用静态 HttpUtility.UrlEncode,但 IDE 无法识别该类,表示它未声明。 我已将命名空间 System.Net 和 System.Web 导入到
如何在窗口应用程序中使用 httpUtility.encode 和 decode。我实现了一个窗口应用程序。此应用程序使用 Web 请求到 Web 服务器。 Web 服务器响应 http 编码版本。那
我是一名优秀的程序员,十分优秀!