github.com/keysonzzz/kmg@v0.0.0-20151121023212-05317bfd7d39/kmgNet/kmgHttp/proxy.go (about) 1 package kmgHttp 2 3 import ( 4 "net/http" 5 "net/url" 6 "strings" 7 ) 8 9 // url明文反向代理. 10 // uri表示,以此uri作为前缀可以进入这个地方,此处代理不会修改用户的uri 11 // 例如: 注册 AddUriProxyToDefaultServer("/data/upload/","http://b.com/") 12 // 用户访问 http://xxx.com/data/upload/745dfc0e7d24b9232a0226116e115967.jpg 此处会去访问 http://b.com/data/upload/745dfc0e7d24b9232a0226116e115967.jpg 13 func AddUriProxyToDefaultServer(uri, targetUrl string) { 14 http.DefaultServeMux.HandleFunc(uri, func(w http.ResponseWriter, req *http.Request) { 15 proxyReq := MustHttpRequestClone(req) 16 target, err := url.Parse(targetUrl) 17 if err != nil { 18 panic(err) 19 } 20 proxyReq.Host = target.Host 21 proxyReq.URL.Host = target.Host 22 proxyReq.URL.Scheme = target.Scheme 23 err = HttpProxyToWriter(w, proxyReq) 24 if err != nil { 25 panic(err) 26 } 27 }) 28 } 29 30 // url明文反向代理. 31 // uri 是否以/开头和结束无所谓, targetUrl 是否以/结束无所谓. 32 // uri表示,以此path作为前缀可以进入这个地方,此处代理可能会修改请求的path 33 // 例如: 注册 MustAddUriProxyRefToUriToDefaultServer("/data/upload/","http://b.com/") 34 // 用户访问 http://xxx.com/data/upload/745dfc0e7d24b9232a0226116e115967.jpg 此处会去访问 http://b.com/745dfc0e7d24b9232a0226116e115967.jpg 35 func MustAddUriProxyRefToUriToDefaultServer(uri, targetUrl string) { 36 uri = "/" + strings.Trim(uri, "/") 37 targetUrlObj, err := url.Parse(targetUrl) 38 if err != nil { 39 panic(err) 40 } 41 handler := func(w http.ResponseWriter, req *http.Request) { 42 proxyReq := MustHttpRequestClone(req) 43 proxyReq.Host = targetUrlObj.Host 44 proxyReq.URL.Host = targetUrlObj.Host 45 proxyReq.URL.Scheme = targetUrlObj.Scheme 46 // uri指向单个文件特殊情况 ("/favicon.ico","http://b.com/favicon.ico" 47 refPath := strings.TrimPrefix(strings.TrimPrefix(req.URL.Path, uri), "/") 48 if refPath == "" { 49 proxyReq.URL.Path = strings.TrimSuffix(targetUrlObj.Path, "/") 50 } else { 51 proxyReq.URL.Path = strings.TrimSuffix(targetUrlObj.Path, "/") + "/" + refPath // 发起请求的时候使用的是 proxyReq.URL.Path 不使用 proxyReq.RequestURI 52 } 53 proxyReq.URL, err = url.Parse(proxyReq.URL.String()) 54 if err != nil { 55 panic(err) 56 } 57 proxyReq.RequestURI = proxyReq.URL.RequestURI() 58 err = HttpProxyToWriter(w, proxyReq) 59 if err != nil { 60 panic(err) 61 } 62 } 63 // 目录 64 http.DefaultServeMux.HandleFunc(uri+"/", handler) 65 // 单文件,由于无法区分是单文件还是目录,只能注册2遍. 66 http.DefaultServeMux.HandleFunc(uri, handler) 67 }