golang实现http(s)代理

2023-10-30

简单原理:

最近需要用golang去实现一个http(s)的代理,简单的解释一下,实现过程就是首先启动一个http(s)的服务,这个很简单,demo一大堆,我就不多说了,接下来要实现代理,很简单的原理就是,通过你实现的http(s)服务接收到来自客户的请求,收到之后通过http.NewRequest建立一次新的请求,当然需要你在配置文件中写明确需要代理到的目标地址和端口,建立新请求到目标地址之后将目标地址返回的数据原封不动的返回给原来的客户端。

注意点:

1、客户端请求的所有头信息,都要原封不动的写入新请求,目标地址返回的头信息也要原封不动的返回给原来的客户端。

2、如果客户端使用https请求的,正常启用https服务能接收到,转发给后端的时候跳过证书就ok,能正常加密传输信息,如果客户端使用http请求的,但我们启动的https server,这样是收不到http发送过来的信息的(好像会给浏览器返回一个不支持http具体的大家可以测试一下),如果严谨一点我们需要自己再启动一个http server,收到请求之后返回302,这样的话一般浏览器都会自动再次转成https请求,再次发送到你的服务端。

3、如果是websocket请求,那就要升级协议了,具体看下一篇博客:

golang代理websocket请求_GT19930910的博客-CSDN博客

具体代码:

package main

import (
    //"encoding/json"
    "fmt"
    "net/http"
    "io/ioutil"
    "strings"
    "io"
)

type HttpProxyHandle struct {
}

func (h *HttpProxyHandle) ServeHTTP(w http.ResponseWriter, req *http.Request) {


    fmt.Printf("Received request: %s %s %s %s\n", req.Method, req.Host, req.RemoteAddr, req.URL)
    config := getConfig()
    fmt.Printf("target server addr:%s\n", config.HttpProxy.Server)

    body, err := ioutil.ReadAll(req.Body)
    if err != nil {
        fmt.Println("body = NULL:", err.Error())
        //return,没有数据也是可以的,不需要直接结束
    }
    fmt.Println("req count:", len(body))

    fmt.Println("send to target server:", config.HttpProxy.Server)

    cli := &http.Client{}

    //配置文件读取详见《golang配置文件与yaml》,http://一定要加
    reqUrl := "http://" + config.HttpProxy.Server + req.URL.String()

      proxy_req, err := http.NewRequest(req.Method, reqUrl, strings.NewReader(string(body)))
    if err != nil {
        fmt.Println("http.NewRequest(to target server addr):", err.Error())
        return
    }

    for k, v := range req.Header {
        proxy_req.Header.Set(k, v[0])
    }

    res, err := cli.Do(proxy_req)
    if err != nil {
        fmt.Println("cli.Do(req):", err.Error())
        return
    }
    defer res.Body.Close()

    for k, v := range res.Header {
        w.Header().Set(k, v[0])
    }
    io.Copy(w, res.Body)
}

func startHttpProxy() {
    c := getConfig()//配置文件读取详见《golang配置文件与yaml》

    s := &http.Server{
        Addr: c.HttpProxy.ListenAddr,//配置文件读取详见《golang配置文件与yaml》
        Handler: &HttpProxyHandle{},
    }

    go func() {
        mainLog.Fatal(s.ListenAndServeTLS(c.HttpApi.CrtFile, c.HttpApi.KeyFile))
    }()
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

golang实现http(s)代理 的相关文章

随机推荐

  • 超强大JS表格:DataViewsJS 1.8.16.1407 Crack

    DataViewsJS完整的 JavaScript 数据呈现和数据网格平台 通过从各种不同的演示视图中进行选择 包括树 卡片 砖石 网格 时间线 甘特图 日历和网格 超越传统的表格显示 快速地 纯 JavaScript 针对速度进行了优化
  • ECMAScript 6规范总结(长文慎入)

    闲话 学习ES6的动机起于对其promise标准的好奇 它与jQuery源码中Deferred不同 而且在异步编程中加入了Generator 在后续ES7中更有Async 这勾起我强烈的兴趣了解ES6更多的内容 于是完整的学习了阮一峰老师的
  • Java Web实战开发基础:MVC模式

    Java Web的MVC模式 MVC是java web的基础 我写的java web实战开发专栏系列都是基于MVC 建议有需要的订阅我专栏的铁铁先提前看看这篇博文哦 简介 Java Web开发中 采用MVC Model View Contr
  • 【华为OD统一考试B卷

    在线OJ 已购买本专栏用户 请私信博主开通账号 在线刷题 运行出现 Runtime Error 0Aborted 请忽略 华为OD统一考试A卷 B卷 新题库说明 2023年5月份 华为官方已经将的 2022 0223Q 1 2 3 4 统一
  • 进程间同步(互斥量、信号量)

    进程间同步可以使用互斥量mutex 互斥锁 信号量和文件锁 进程间同步使用信号量 int sem init sem t sem int pshared unsigned int value 用于进程间同步此时第二个参数不能取0了 取非0值用
  • stm32中can通讯的基本概念

    身为一个电控组的成员 我们当接触一个新的概念的时候首先应该去了解他的硬件 其次再者是软件 而且在学习新的应用时 也应该清楚什么我们要着重了解 什么我们要清楚即可 以can为例 我们先从他的硬件说起 Can硬件一共有两种接法 但核心还是两根信
  • Tomcat服务器的HTTP首部长度最大值

    今天编写Cas5 OAuth2 0 实现password 授权功能时 Tomcat 提示如下信息 HTTP 头部长度超出默认长度 解决方法 配置文件路径 TOMCAT HOME conf server xml 修改如下 添加头部最大值 81
  • 1一个HTTP请求的网络脉络,解压爽文

    一个HTTP请求的网络脉络 解压爽文 1写前的话 2 网络请求概览 2 1 http 的产生 2 1 1什么叫做协议 2 1 2http定义 2 1 3 http诞生历史 怎么来的 时间迭代史 2 1 4浏览器的小插曲 2 2tcp ip协
  • 开发者入门必读:最值得看的十大机器学习公开课

    转 http www leiphone com news 201701 0milWCyQO4ZbBvuW html 导语 入门机器学习不知道从哪着手 看这篇就够了 在当下的机器学习热潮 人才匮乏十分显著 截至目前 国内开设人工智能 AI 专
  • R语言时间序列之ARMA、ARIMA模型

    基本理论知识 ARMA模型称为自回归移动平均模型 是时间序列里常用的模型之一 ARMA模型是对不含季节变动的平稳序列进行建模 它将序列值表示为过去值和过去扰动项的加权和 模型形式如下 yt c a1yt 1 a2yt 2 apyt p t
  • 【图像识别】基于卷积神经网络CNN和支持向量机SVM实现花卉图像识别附matlab代码...

    作者简介 热爱科研的Matlab仿真开发者 修心和技术同步精进 matlab项目合作可私信 个人主页 Matlab科研工作室 个人信条 格物致知 内容介绍 针对传统图像分类算法在泛化能力等方面存在的不足 结合当前的深度学习算法 提出一种基于
  • 显示器尺寸对照表_怎样知道自己的电脑显示器是多少寸的

    展开全部 直接测量显示器e5a48de588b662616964757a686964616f31333366303731对角线即可 不包括边框 测量结果除以2 45得数就是显示器尺寸 显示器 display 通常也被称为监视器 显示器是属于
  • 20个基于DPDK开源项目,建议收藏

    一 ANS DPDK 原生加速网络堆栈 ANS 加速网络堆栈 是DPDK本地TCP IP堆栈 也参考FreeBSD实现 ANS提供了一个与Intel DPDK一起使用的用户空间TCP IP堆栈 文件结构 ans 加速网络堆栈过程 librt
  • FireFly菜鸟学习二(cocos2dx客户端和服务器通信实现)

    1 FireFly服务器 FireFly自定义通信协议 coding utf8 from firefly server globalobject import netserviceHandle from firefly server glo
  • kali安装SRC挖掘利器—ARL(Asset Reconnaissance Lighthouse)资产侦察灯塔系统安装教程

    目录 先参考kali安装Docker 卸载旧版本 配置Docker以在启动时启动 Linux的安装后步骤 Docker 启动 文章参考地址 https www 77169 net download 267781 html 本地搭建 Kali
  • 对extern,static,const的再认识

    const const修饰的值为常量 是不可改变的 在c 语言中是不可改变的 而在C语言中 我们可以通过指针去修改那一片地址的值 const修饰的指针 表面指针指向或者指针的值是不可被修改的 我们可以通过通配符 的位置来判断 在左说明修饰的
  • 测试计划等模板

    一 测试计划 测试范围 测试策略 测试资源 人员分配 时间安排 进度 风险评估 测试目的 测试背景 二 测试用例 测试用例编号 标题 所属模块 前置条件 操作步骤 输入数据 预期结果 实际结果 三 缺陷报告 缺陷编号 缺陷标题 缺陷状态 缺
  • vue-cropper 截图组件踩坑记

    安装 npm install save vue cropper 封装组件
  • 刷脸支付不用排队节约了时间

    科技改变人们生活 科技推动人类社会进步 近几年移动支付崛起 让人们实现了 一个手机走天下 的便捷 而如今 随着人工智能 大数据等技术的积累突破 支付方式再一次出现重大突破 即将从手机移动支付跨越到刷脸支付时代 据了解 刷脸支付技术已经成熟
  • golang实现http(s)代理

    简单原理 最近需要用golang去实现一个http s 的代理 简单的解释一下 实现过程就是首先启动一个http s 的服务 这个很简单 demo一大堆 我就不多说了 接下来要实现代理 很简单的原理就是 通过你实现的http s 服务接收到