一个利用go反向代理解决api转发的例子(go反向代理)
实现的效果:
如果访问的url路径是类似 /163/ 或 /163/debian 的形式,则转发到163开源镜像服务器
直接上代码:
package main import (
"fmt"
"log"
"net/http"
"net/http/httputil"
"net/url"
) var fwdHost = "mirrors.163.com" //http首部字段的HOST取值
var fwdTo = "http://" + fwdHost + "/"
var fwdPrefix = "/163/" type forward struct {
RProxy *httputil.ReverseProxy
} func (f *forward) ServeHTTP(wr http.ResponseWriter, req *http.Request) {
//fmt.Printf("http头部是:%+v\n", req.Header) //假设这是处理http头部的代码
fmt.Printf(" #### REQ:%+v\n", req) //处理完后转发到网易163镜像
req.URL.Path = req.URL.Path[len(fwdPrefix)-1:] //修改了这里,req.RequestURI会跟着变
req.Host = fwdHost
fmt.Printf(" *** REQ:%+v\n", req)
f.RProxy.ServeHTTP(wr, req)
} func main() {
var fwd forward
u, _ := url.Parse(fwdTo)
fwd.RProxy = httputil.NewSingleHostReverseProxy(u)
http.Handle(fwdPrefix, &fwd) //所有请求将转发到网易163的debian镜像
http.HandleFunc("/", notForward)
http.HandleFunc("/api/v1/", notForward)
log.Fatal(http.ListenAndServe(":3000", nil))
} func notForward(wr http.ResponseWriter, req *http.Request) {
wr.Write([]byte(fmt.Sprintf(`<html>
<body>
<em>Not forward!!</em>
<br />
<i>url = %s</i>
</body>
</html>
`,req.URL.String())))
}
类似的还有更简单的做法,关键在httputil.ReverseProxy的Director字段:
func APIReverseProxy(host string) http.HandlerFunc {
var rp = httputil.ReverseProxy{
Director:func(req *http.Request) {
req.URL.Scheme = "http"
req.URL.Host = host
req.Host = host //对于一个ip地址托管多个域名的情况下,必须要给req.Host赋值,如果一个ip地址只有一个域名,可以不写这一句
//req.URL.Path = //如果需要改path的话
},
}
return func(wr http.ResponsWriter, req *http.Request){
rp.ServeHTTP(wr,req)
} //这里是返回http.HandlerFunc的例子,其实也可以直接返回rp(因为*rp就是一个http.Handler, *rp实现了ServeHTTP(wr,req)方法)
}
关于req.URL.Host和req.Host:
go http包中对request中Host的注释:
// For server requests Host specifies the host on which the
// URL is sought. Per RFC 2616, this is either the value of
// the "Host" header or the host name given in the URL itself.
// It may be of the form "host:port". For international domain
// names, Host may be in Punycode or Unicode form. Use
// golang.org/x/net/idna to convert it to either format if
// needed.
//
// For client requests Host optionally overrides the Host
// header to send. If empty, the Request.Write method uses
// the value of URL.Host. Host may contain an international
// domain name.
Host string
另外:
req.URL.Host是从URL中解析出来的,
req.Host是http请求头部"Host" , 这个头部用于实现虚拟主机(一个ip托管多个域名),http1.1规范中,Host头是必须存在的
对于下面的请求:
GET /index.html HTTP/1.1
Host: www.example.org:8080
req.URL.Host是空的
对于通过代理的请求,req.URL.Host是目标主机,req.Host是代理服务器。
对于不是走代理的请求,req.URL.Host是空的,req.Host是目标主机
一个利用go反向代理解决api转发的例子(go反向代理)的更多相关文章
- windows环境下 nginx+iis 反向代理解决跨域问题
项目基本完成,是时候花点时间整理一下最近的姿势了 1 什么是跨域? 网上对于跨域的概念会有大篇幅的文章去解释,似乎有点玄乎,初学者很容易对这个概念产生恐惧,跨域其实很简单,其实只要知道一点,无法跨域访 ...
- 利用nginx做反向代理解决前端跨域问题
最近朋友再群里提了一个问题,他们公司给他提供了一个获取数据的接口,在浏览器访问这个接口能获取到json数据,但是放在项目里使用ajax就产生了跨域问题,一般这个需要提供接口的后台方面需要做跨域处理,但 ...
- 前端通过Nginx反向代理解决跨域问题
在前面写的一篇文章SpringMVC 跨域,我们探讨了什么是跨域问题以及SpringMVC怎么解决跨域问题,解决方式主要有如下三种方式: JSONP CORS WebSocket 可是这几种方式都是基 ...
- nginx反向代理-解决前端跨域问题
1.定义 跨域是指a页面想获取b页面资源,如果a.b页面的协议.域名.端口.子域名不同,所进行的访问行动都是跨域的,而浏览器为了安全问题一般都限制了跨域访问,也就是不允许跨域请求资源.注意:跨域限制访 ...
- nginx反向代理解决跨域问题
跨域:浏览器从一个域名的网页去请求另一个域名的资源时,域名.端口.协议任一不同,都是跨域 . 下表格为前后端分离的域名,技术信息: 域名 服务器 使用技术 前端 http://b.yynf.com ...
- Nginx入门及如何反向代理解决生产环境跨域问题
1.Nginx入门与基本操作篇 注:由于服务器是windows系统,所以本文主要讲解Nginx在windows下的操作. 首先下载Nginx 解压缩,我们所有的配置基本都在万能的 nginx/conf ...
- Nginx 反向代理解决跨域问题分析
当你遇到跨域问题,不要立刻就选择复制去尝试.请详细看完这篇文章再处理 .我相信它能帮到你. 分析前准备: 前端网站地址:http://localhost:8080 服务端网址:http://local ...
- [转]用apache反向代理解决单外网ip对应内网多个web主机的问题
用apache反向代理解决单外网ip对应内网多个web主机的问题 转载一个有独立外网IP,需内网服务器对外发布的例子,是应用apache虚拟主机的. 来源地址:http://www.itshantou ...
- 使用 ssh -R 建立反向/远程TCP端口转发代理
转自:https://yq.aliyun.com/articles/8469 ssh是一个非常棒的工具, 不但能建立动态转发, 例如chrome的Switchy插件用到的就是这个技术.http://b ...
- 使用nginx反向代理解决前端跨域问题
1. 首先去Nginx官网下载一个最新版本的Nginx,下载地址:http://nginx.org/en/download.html.我这里下载的版本是:nginx/Windows-1.12.0.下载 ...
随机推荐
- SAP标准附件-GOS(generic object service)
标准附件功能显示需要用户是 A类型 对话用户 本文介绍一个Public Class :CL_GOS_DOCUMENT_SERVICE 该类包含了创建附件,注释,URL,个人注释等方法,这些方法中都会涉 ...
- How to Use Github
C:\Windows\System32\drivers\etc\hosts 在最后加上一句 20.205.243.166 github.com 从 https://ping.chinaz.com/ 来 ...
- TienChin 渠道管理-工程创建
因为本文章主要围绕着项目开发进行,所以前言不做开头,直接上内容. 添加字段 我们的渠道表,我看到若依脚手架当中有一个是否删除的标志字段,所以我这里也添加一下: ALTER TABLE `tienchi ...
- 【三】AI Studio 项目详解——单机多机训练分布式训练--PARL
相关文章 [一]-环境配置+python入门教学 [二]-Parl基础命令 [三]-Notebook.&pdb.ipdb 调试 [四]-强化学习入门简介 [五]-Sarsa&Qlear ...
- git操作 手写稿
- 深入浅出Java多线程(四):线程状态
引言 大家好,我是你们的老伙计秀才!今天带来的是[深入浅出Java多线程]系列的第四篇内容:线程状态.大家觉得有用请点赞,喜欢请关注!秀才在此谢过大家了!!! 在现代软件开发中,多线程编程已经成为提升 ...
- PicGo + Gitee 实现 Markdown 图床
最近再研究图床,注册的阿里云域名备案还在审批,所以七牛云图床暂时没用,所以试下用PicGo+ Gitee PicGo - 基于 electron-vue 开发的图床工具 PicGo目前支持了微博图床, ...
- Dijkstra实现单源最短路
Dijkstra算法求单源最短路 Dijkstra算法应用于求一个给定图的单个源点到其他各顶点的最短路.其中应用Dijkstra算法的图应满足如下条件 图中没有负权边 有向或者无向图都可以 图中若有自 ...
- .NET 云原生架构师训练营(模块二 基础巩固 MySQL环境准备)--学习笔记
2.4.1 EF Core -- MySQL环境准备 安装 Docker 配置 docker 镜像仓库国内镜像地址 运行 mysql docker container 通过 Navicate 连接 安 ...
- OGG-将PostgreSQL通过OGG_BigData同步到Kafka后数据存在8小时时间差
问题描述: 将PostgreSQL通过OGG_BigData同步到Kafka后数据存在8小时时间差. 问题原因: kafka.properties中的参数goldengate.userexit.tim ...