http 代理有什么用处?

1,可以是插入 js 广告,某些 isp 就是这么干的,强插广告,现在 https 的网站越来越多了,插入不了。

2,  用来调试 app 或是别的程序,可以看到详细的 http 请求,响应,fiddler 这个软件也是做这个的,但它不开源。

用浏览器打开测试的 HTTP 请求  http://localhost/logo.gif  带端口号的  http://localhost:8000/logo.gif

使用 wireshark 抓包:

GET http://localhost/logo.gif HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:56.0) Gecko/ Firefox/56.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1 #或第 2 种
GET http://localhost:8000/logo.gif HTTP/1.1
Host: localhost:8000
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:56.0) Gecko/20100101 Firefox/56.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
DNT:
Connection: keep-alive
Upgrade-Insecure-Requests:

原理:

http 1.1 也就是 tcp 连接,有 header 和 body ,更多复杂的细节这里不做介绍(session cookie 缓存等)

下面使用 python 实现,  listen 8000 端口,分析原始的 请求网址的HOST 和端口,建立连接拿回数据转发。

设置浏览器,使用 localhost 8000 http 代理方式 。

下图以 firefox 设置为例:

源码 py2.7:

 #!/usr/bin/env python
#coding:utf-8
import socket
import sys
import re
import os
import time
import urllib
import urllib2
import threading HEADER_SIZE = 4096 host = '0.0.0.0'
port = 8000 #子进程进行socket 网络请求
def http_socket(conn, addr):
print("client connent:{0}:{1}".format(addr[0], addr[1]))
try:
#读取 http 请求头信息
request_header = conn.recv(HEADER_SIZE)
#拆分头信息
host_addr = request_header.split("\r\n")[1].split(":")
#如果未指定端口则为默认 80
if 2 == len(host_addr):
host_addr.append("")
name, host, port = map(lambda x: x.strip(), host_addr)
#建立 socket tcp 连接
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, int(port)))
#发送原始请求头
sock.sendall(request_header)
#接收数据并发送给浏览器
while(True):
resp = sock.recv(512)
if resp:
conn.sendall(resp)
else:
break
#关闭连接
sock.close()
except Exception as e:
print("http socket error")
print(e) #创建socket对象
http_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
http_server.bind((host, port))
except:
sys.exit("python proxy bind error ") print("python proxy start") http_server.listen(1024) while True:
conn, addr = http_server.accept()
http_thread = threading.Thread(target=http_socket, args=(conn, addr))
http_thread.start()
time.sleep(1) #关闭所有连接
http_server.close()
print("python proxy close")

测试下载大点的文件:

正常。

缺点是,性能不好,没有实现 Connection : keep-alive 打开一次就关闭了。

在 win10 python2.7 ubuntu 16.0.4 上应该都可以用

select 版 修改了 keep-alive 不是每次都关闭连接

 #!/usr/bin/env python
#coding:utf-8
import socket
import sys
import re
import os
import time
import select
import threading HEADER_SIZE = 4096 host = '0.0.0.0'
port = 8000 #子进程进行socket 网络请求
def http_socket(client, addr):
#创建 select 检测 fd 列表
inputs = [client]
outputs = []
remote_socket = 0
print("client connent:{0}:{1}".format(addr[0], addr[1]))
while True:
readable, writable, exceptional = select.select(inputs, outputs, inputs)
try:
for s in readable:
if s is client:
#读取 http 请求头信息
request_header = s.recv(HEADER_SIZE)
if remote_socket is 0:
#拆分头信息
host_addr = request_header.split("\r\n")[1].split(":")
#如果未指定端口则为默认 80
if 2 == len(host_addr):
host_addr.append("")
name, host, port = map(lambda x: x.strip(), host_addr)
#建立 socket tcp 连接
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, int(port)))
remote_socket = sock
inputs.append(sock)
#发送原始请求头
remote_socket.sendall(request_header)
else:
#接收数据并发送给浏览器
while(True):
resp = s.recv(512)
if resp:
client.sendall(resp)
else:
break
except Exception as e:
print("http socket error {0}".format(e)) #创建socket对象
http_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
http_server.bind((host, port))
except:
sys.exit("python proxy bind error ") print("python proxy start") http_server.listen(1024) while True:
client, addr = http_server.accept()
http_thread = threading.Thread(target=http_socket, args=(client, addr))
http_thread.start()
time.sleep(1) #关闭所有连接
http_server.close()
print("python proxy close")

https 的实现稍复杂一点,下面讲。

python 实现简单 http 代理的更多相关文章

  1. python 单例模式获取IP代理

    python 单例模式获取IP代理 tags:python python单例模式 python获取ip代理 引言:最近在学习python,先说一下我学Python得原因,一个是因为它足够好用,完成同样 ...

  2. 简介Python设计模式中的代理模式与模板方法模式编程

    简介Python设计模式中的代理模式与模板方法模式编程 这篇文章主要介绍了Python设计模式中的代理模式与模板方法模式编程,文中举了两个简单的代码片段来说明,需要的朋友可以参考下 代理模式 Prox ...

  3. Python爬虫简单实现CSDN博客文章标题列表

    Python爬虫简单实现CSDN博客文章标题列表 操作步骤: 分析接口,怎么获取数据? 模拟接口,尝试提取数据 封装接口函数,实现函数调用. 1.分析接口 打开Chrome浏览器,开启开发者工具(F1 ...

  4. Python 实现简单的 Web

    简单的学了下Python, 然后用Python实现简单的Web. 因为正在学习计算机网络,所以通过编程来加强自己对于Http协议和Web服务器的理解,也理解下如何实现Web服务请求.响应.错误处理以及 ...

  5. 用 python实现简单EXCEL数据统计

    任务: 用python时间简单的统计任务-统计男性和女性分别有多少人. 用到的物料:xlrd 它的作用-读取excel表数据 代码: import xlrd workbook = xlrd.open_ ...

  6. python开启简单webserver

    python开启简单webserver linux下面使用 python -m SimpleHTTPServer 8000 windows下面使用上面的命令会报错,Python.Exe: No Mod ...

  7. Python开发简单爬虫 - 慕课网

    课程链接:Python开发简单爬虫 环境搭建: Eclipse+PyDev配置搭建Python开发环境 Python入门基础教程 用Eclipse编写Python程序   课程目录 第1章 课程介绍 ...

  8. python使用简单http协议来传送文件

    python使用简单http协议来传送文件!在ubuntu环境下,局域网内可以使用nc来传送文件,也可以使用基于Http协议的方式来下载文件我们可以使用python -m SimpleHTTPServ ...

  9. Python超简单的HTTP服务器

    Python超简单的HTTP服务器 安装了python就可以 python -m SimpleHTTPServer 执行这一个命令即可实现一个HTTP服务器,将当前目录设为HTTP服务目录,可以通过h ...

随机推荐

  1. 【7集iCore3基础视频】7-6 Quartus II 13.1安装

    Quartus II 13.1安装:高清源视频:链接:http://pan.baidu.com/s/1csVRMA 密码:lkth 视频勘误:http://pan.baidu.com/s/1mhCIq ...

  2. FTP上传文件提示550错误原因分析。

    今天测试FTP上传文件功能,同样的代码从自己的Demo移到正式的代码中,不能实现功能,并报 Stream rs = ftp.GetRequestStream()提示远程服务器返回错误: (550) 文 ...

  3. Linux Vsftpd 连接超时解决方法(被动模式)

    http://blog.csdn.net/qq_15766181/article/details/46554643 使用 FileZilla FTP Client 连接 Vsftpd FTP,在没有配 ...

  4. C++笔记----构造函数与析构函数(三)

    1.构造函数初始化列表 推荐在构造函数初始化列表中进行初始化 构造函数的执行分为两个阶段:初始化段. 普通计算段 2.对象成员及其初始化 #include<iostream> using ...

  5. JMeter学习-022-JMeter 分布式测试(性能测试大并发、远程启动解决方案)

    在使用 JMeter 进行性能测试时,难免遇到要求并发请求数比较的场景,此时单台测试机的配置(CPU.内存.带宽等)可能无法支持此性能测试场景.因而,此时 JMeter 提供的分布式测试功能就有了用武 ...

  6. 理解JAVA - 面向对象(object) - 属性,方法

    理解JAVA - 面向对象(object) - 属性,方法 多态的体现:    向上造型,父类接收子类对象:向上造型:    从父类角度看不到子类独有的方法:面向对象,人类认知世界的方式:生活中每天都 ...

  7. 2003-can't connect to mysql server on 'localhost'(10061) MySQL错误

    开始遇到这个问题,我以为是服务没链接,在网上查了下错误,但没解决,后来链接了下端口,结果发现我原来我 端口不对,MySQL端口默认是3306我安装时端口是设的3307.希望能帮到遇到这种问题的人

  8. kafka Failed to send messages after 3 tries 问题解决

    kafka Failed to send messages after 3 tries. 在kafka0.8开发过程中 生产者测试用例碰到了 Exception in thread "mai ...

  9. 导出csv文件示例

    导出csv文件示例 csv文件默认以英文逗号,做为列分隔符换行符\n作为行分隔符,写入到一个.csv文件即可.含有英文逗号,和换行符会发生数据输出会出现混乱,下面列出一些处理方法.特殊字符处理1.含有 ...

  10. 使用HTTPS网站搭建iOS应用内测网站(OTA分发iOS应用)

    为什么要搭建应用内测网站呢? 1.AppStore的审核速度比较慢,万一被拒,还得等,而且一旦发布,任何人都可以下载,而有些时候只有老板想知道最新的修改是否符合要求,万一不符合要求呢?又要修改了. 2 ...