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. PHP 检测变量是否为空

    PHP 中以下值得计算结果为 false: 关键字 boolean false 整型 integer 0 浮点型 double 0.0 字符串 string ""  字符串 str ...

  2. NodeJs并发异步的回调处理

    这里说并发异步,并不准确,应该说连续异步.NodeJs单线程异步的特性,直接导致多个异步同时进行时,无法确定最后的执行结果来回调.举个简单的例子: for(var i = 0; i < 5; i ...

  3. Hardware Solutions CACHE COHERENCE AND THE MESI PROTOCOL

    COMPUTER ORGANIZATION AND ARCHITECTURE DESIGNING FOR PERFORMANCE NINTH EDITION Hardware-based soluti ...

  4. github for window的代理设置方法

    修改 .gitconfig 文件,主要是针对http 和 https进行修改,设置代理 [user] name = name email = mail@.com [http] proxy = 配置文件 ...

  5. Arduino.h

    #ifndef Arduino_h #define Arduino_h #include <stdlib.h> #include <stdbool.h> #include &l ...

  6. 给定一个double类型的数组arr,其中的元素可正可负可0,返回子数组累乘的最大乘积。例如arr=[-2.5,4,0,3,0.5,8,-1],子数组[3,0.5,8]累乘可以获得最大的乘积12,所以返回12。

    分析,是一个dp的题目, 设f[i]表示以i为结尾的最大值,g[i]表示以i结尾的最小值,那么 f[i+1] = max{f[i]*arr[i+1], g[i]*arr[i+1],arr[i+1]} ...

  7. java常见的开发工具

    http://www.csdn.net/article/1970-01-01/2824723 http://zhidao.baidu.com/link?url=D8FdJxeFd-z-LV1OfZuZ ...

  8. delphi之TDataset

    最近遇到了很多问题,现在做一下总结. 字符串处理: 字符串相加 var S1, S2: String; begin S1 := Concat('A', 'B'); // 连接两个字符串,S1变量等于A ...

  9. java内省机制及PropertyUtils使用方法

    背景 一般情况下,在Java中你可以通过get方法轻松获取beans中的属性值.但是,当你事先不知道beans的类型或者将要访问或修改的属性名时,该怎么办?Java语言中提供了一些像java.bean ...

  10. 流量三角形:并非简单的"统计学"

    又忙了一周多,今天过来再整理一些东西.国内做产险精算的,准备金的居多,从精算部落中的帖子的跟帖情况可见一斑.既然准备金更容易受到大家的关注,今天再整理一个关于准备金的个人看法,给精算部落收敛一下人气, ...