Http代理穿透

原理

HTTP代理服务器中能够提供一种HTTP CONNECT代理服务,能够允许用户建立TCP连接到任何端口。通过CONNECT方法穿透代理的实现方法为:
CONNECT代理服务器的代理端口(如:8080);如果成功返回就可以按照正常的Socket进行通讯。当然在此之前需要先获得代理相关的信息。
如何获取HTTP代理相关信息
程序中是通过读取注册表来获取计算机HTTP代理相关信息的,在注册表的\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings键值下就保存着HTTP代理服务器及端口等信息,
根据该键值下的ProxyEnable值可以判断是否有HTTP代理,没有代理的情况下ProxyEnable值为0。
当然一般情况下程序去中访问该键值可能是受限的,所有就需要获取到访问令牌不受限制的UserSid,使用该UserSid去读取HTTP代理信息。

char tmpBuffer[128] = { 0 }; ::sprintf(tmpBuffer, "CONNECT %s:%d HTTP/1.1\r\nUser-Agent: Mozilla/4.0\r\nConnection: Keep-Alive\r\n\r\n", ip.c_str(), port); Send(tmpBuffer, strlen(tmpBuffer)); Receive(tmpBuffer, sizeof(tmpBuffer));

实现

头文件

#pragma once #include <string> #include <vector> using namespace std; class addrinfo; class CHttpProxy { public: CHttpProxy(std::string ip, unsigned short port) :m_proxyIp(ip), m_proxyPort(port), m_socket(-1) {} ~CHttpProxy(void); void ConnectProxyServer(); void ConnectServer(std::string ip, unsigned short port); bool Send(const char* buf, int len); int Receive(char* buf, int bufLen); int GetSocket() { return m_socket; } private: std::string m_proxyIp; addrinfo* m_addrinfo = nullptr; unsigned short m_proxyPort; int m_socket; };

实现

#include "HttpProxy.h" #include <string.h> #include <time.h> #ifdef WIN32 #include <WS2tcpip.h> #else #include <unistd.h> #include <netdb.h> #include <arpa/inet.h> #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> #include <netinet/in.h> #define INVALID_SOCKET -1 #endif CHttpProxy::~CHttpProxy(void) { if (m_addrinfo) { freeaddrinfo(m_addrinfo); } } void CHttpProxy::ConnectProxyServer() { struct sockaddr_in addr; m_socket = socket(AF_INET, SOCK_STREAM, 0); if (m_socket == INVALID_SOCKET) { throw CException("Error on creating socket fd"); } addrinfo inAddrInfo = { 0 }; inAddrInfo.ai_family = AF_INET; inAddrInfo.ai_socktype = SOCK_STREAM; std::string strPort = std::to_string(m_proxyPort); if (getaddrinfo(m_proxyIp.c_str(), strPort.c_str(), &inAddrInfo, &m_addrinfo) != 0) // error occurs { throw CException("Error on calling getadrrinfo()."); } if (connect(m_socket, m_addrinfo->ai_addr, m_addrinfo->ai_addrlen)) { throw CException("Error on calling connect()."); } } void CHttpProxy::ConnectServer(std::string ip, unsigned short port) { if (m_socket == INVALID_SOCKET) { throw CException("Invalid socket fd"); } char tmpBuffer[128] = { 0 }; ::sprintf(tmpBuffer, "CONNECT %s:%d HTTP/1.1\r\nUser-Agent: Mozilla/4.0\r\nConnection: Keep-Alive\r\n\r\n", ip.c_str(), port); Send(tmpBuffer, strlen(tmpBuffer)); Receive(tmpBuffer, sizeof(tmpBuffer)); int mj, mi, code; ::sscanf(tmpBuffer, "HTTP/%d.%d %d", &mj, &mi, &code); if (code != 200) { throw CException("http connect emial server faild"); } } int CHttpProxy::Receive(char* buf, int bufLen) { return recv(m_socket, buf, bufLen, 0); } bool CHttpProxy::Send(const char* buf, int len) { long ilen = len; int sendCnt = 0; int ret; while (sendCnt < ilen) { if ((ret = send(m_socket, buf + sendCnt, ilen - sendCnt, 0)) == INVALID_SOCKET) { return false; } else { sendCnt += ret; } } return true; }
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

HTTP、HTTPS常用的默认端口号

端口号标识了一个主机上进行通信的不同的应用程序。1.HTTP协议代理服务器常用端口号:80/8080/3128/8081/90982.SOCKS代理协议服务器常用端口号:10803.FTP(文件传输)协议代理服务器常用端口号:214.Telnet(远程登录)协议代理服务器常用端口号:23HTTP服务器,默认端口号为80/tcp(木马Exe

Nginx是什么及作用?

一:介绍nginx是一个高性能的HTTP和反向代理服务器,其特点是占用内存少,并发能力强。二:名词介绍代理服务器:代理服务器英文全称是ProxyServer,其功能就是代理网络用户去取得网络信息。形象的说:它是网络信息的中转站,去获取信息。主要的功能有:1.突破自身IP访问限制,访问国外站点。教育网、169网等

OkHttp3中的代理与路由

路由是什么呢?路由即是网络数据包在网络中的传输路径,或者说数据包在传输过程中所经过的网络节点,比如路由器,代理服务器之类的。那像OkHttp3这样的网络库对于数据包的路由需要做些什么事呢?用户可以为终端设置代理服务器,HTTP/HTTPS代理或SOCK代理。OkHttp3中的路由相关逻辑,需要从系统中获取用户设置的代理服务器的地址,将HTTP请求转换为代