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. C fwrite

    功能:向文件读入写入一个数据块. 用法:fwrite(const void *buffer,size_t size,size_t count,FILE *stream); (1)buffer:是一个指 ...

  2. 小型移动 webApp Demo 知识点整理

    包括内容: css初始化.css全局设置.常用meat标签.rem适配.flex布局.相关技巧(手势库使用.多行截字.1像素边线.点击状态.placeholder居中等) reset 引用 norma ...

  3. Apache Spark技术实战之8:Standalone部署模式下的临时文件清理

    未经本人同意严禁转载,徽沪一郎. 概要 在Standalone部署模式下,Spark运行过程中会创建哪些临时性目录及文件,这些临时目录和文件又是在什么时候被清理,本文将就这些问题做深入细致的解答. 从 ...

  4. 利用navicat创建存储过程、触发器和使用游标的简单实例

    利用navicat创建存储过程.触发器和使用游标的简单实例 标签: navicat存储过程触发器mysql游标 2013-08-03 21:34 15516人阅读 评论(1) 收藏 举报  分类: 数 ...

  5. ssh 文件权限影响登录

    进入/etc/ssh目录 需要保证文件访问控制权限如下: ssh_host_dsa_key 600 ssh_host_ras_key 600

  6. JS操作cookie

    JavaScript中的另一个机制:cookie,则可以达到真正全局变量的要求.cookie是浏览器 提供的一种机制,它将document 对象的cookie属性提供给JavaScript.可以由Ja ...

  7. 60个有用CSS代码片段

    1.垂直对齐 如果你用CSS,则你会有困惑:我该怎么垂直对齐容器中的元素?现在,利用CSS3的Transform,可以很优雅的解决这个困惑: .verticalcenter{ position: re ...

  8. QDirModel

    #include "dialog.h" #include "ui_dialog.h" #include<QInputDialog> Dialog:: ...

  9. DataTable数据赋值给Model通用方法

    注:该文属本人原创,今后项目中发现该方法存在BUG会实时更新,转载记得附上原文出处,方便大家获得最新代码. 相信大家在做项目中,经常会根据不同的表new各种不同的Model,当需要对Model进行实例 ...

  10. JSON字符串与JSON对象的区别

    Q:什么是"JSON字符串",什么是"JSON对象",两者的区别? a.JSON对象是直接可以使用JQuery操作的格式,如C#中可以用对象(类名)点出属性(方 ...