这个项目实现了:

a) 网站过滤:允许/不允许访问某些网站;

b) 用户过滤:支持/不支持某些用户访问外部网站;

c) 网站引导:将用户对某个网站的访问引导至一个模拟网站(钓

鱼)。

d) 缓存功能:要求能缓存原服务器响应的对象,并能够通过修改请求报文(添加 if-modified-since头行),向原服务器确认缓存对象是否是最新版本

首先,先要把django包内的C:\Python27\Lib\site-packages\django\core\handlers\base.py 中的^$改为.* 。(共有两处需要修改),以此来保证能让所有的url目标都传到views里面的函数中。

如图

然后构建一个django项目,可以不带有admin模块,然后建立一个新的app

博主构建的项目结构如下,其中Cache.py是一会再创建的

下面是models.py的代码

#coding=utf8
from django.db import models class fish(models.Model):
#钓鱼规则表
user_ip = models.CharField(max_length=15) #客户ip
forbidden_host = models.CharField(max_length=100) #禁止的host
fish_url = models.CharField(max_length=100) #跳转的网站链接 class firewall(models.Model):
#黑名单规则表
user_ip = models.CharField(max_length=15) #客户ip
forbidden_host = models.CharField(max_length=100) #禁止的host class cache(models.Model):
#缓存表
timestamp = models.CharField(max_length=80) #时间戳
name = models.CharField(max_length=150) #文件名对应的url
content_type = models.CharField(max_length=50) #内容类型
content = models.TextField() #内容 def check_if_replace(user_ip, host):
user_list = firewall.objects.filter(user_ip=user_ip).all() #先到黑名单中查找
for user in user_list:
if user.forbidden_host in host or host == '*':
return (1, '<h1>You have been forbidden!</h1>') #返回禁止页
general = firewall.objects.filter(user_ip='*').all()
for i in general:
if i.forbidden_host in host:
return (1, '<h1>You have been forbidden!</h1>')
fish_list = fish.objects.filter(user_ip=user_ip).all() #然后到钓鱼规则中查找
for fisher in fish_list:
if fisher.forbidden_host in host:
return (-1, fisher.fish_url)
return (0, host)

这一部分是用来做规则的存储和缓存的存储,migrate之后各表如下所示



这张表用来做禁止规则的配置,可以用'*'作为通配符,实现所有用户对单一网站和对某用户做屏蔽。



这张表用来做钓鱼规则的配置,用户转到指定的目标



这张表作为缓存的实现

views.py的代码:

#coding=utf8
import re
from contextlib import closing
from django.http import HttpResponse,HttpResponseRedirect
from Cache import *
def home(request):
url = request.path[1:].split('/')
url = url[0] + '//' + url[1] + '/'
url = request.path[1:].replace(':/', '://') #获得目标url
host = request.get_host()
method = request.method
if request.META.has_key('HTTP_X_FORWARDED_FOR'):
ip = request.META['HTTP_X_FORWARDED_FOR'] #获取客户端ip
else:
ip = request.META['REMOTE_ADDR']
regex = re.compile('^HTTP_')
headers = dict((regex.sub('', header), value) for (header, value)
in request.META.items() if header.startswith('HTTP_'))
if len(request.REQUEST.items()) > 0:
url += '?'
for (i, j) in request.REQUEST.items():
url += str(i) + '=' + str(j) + '&'
url = url[:-1] #将带参数的get请求恢复成原始链接状态
check_tuple = check_if_replace(ip, host)
if check_tuple[0] == 1:
return HttpResponse(check_tuple[1]) #如果符合黑名单规则,返回禁止页
elif check_tuple[0] == -1:
url = check_tuple[1]
return HttpResponseRedirect(url) #如果符合钓鱼规则,那么重定向到指定的网站
cacher = Cache(url)
if cacher.check_cache(): #检查是否有与目标网站一致的资源
res = cacher.get()
return HttpResponse(res[0], content_type=res[1]) #将缓存的内容返回
else:
with closing(requests.request(method, url, headers=headers, data=request.POST, stream=True)) as r:
cacher.update(bytes(r.content), content_type=r.headers['content-type']) #更新缓存
return HttpResponse(bytes(r.content), status=r.status_code, content_type=r.headers['content-type']) #返回资源

Cache.py的代码

#coding=utf8
import requests
from models import *
import time
class Cache():
def __init__(self, url):
self.url = url def check_cache(self):
'''
检查是否有一致的缓存
:return: Boolean型
'''
try:
f = cache.objects.get(name=self.url)
headers = {'If-Modified-Since': f.timestamp}
if requests.get(self.url, headers=headers).status_code == 304:
return True
else:
return False
except:
return False def update(self, content, content_type):
'''
更新缓存
:param content: 内容
:param content_type: 内容类型
:return:
'''
try:
f = cache.objects.get(name=self.url)
f.content = content
f.content_type = content_type
f.name = self.url
t = time.asctime().split()
f.timestamp = t[0] + ', '+t[2] + ' '+t[1] +' '+t[4]+' '+t[3] + 'GMT'
f.save()
except:
f = cache()
f.content = content
f.name = self.url
t = time.asctime().split()
f.timestamp = t[0] + ', ' + t[2] + ' ' + t[1] + ' ' + t[4] + ' ' + t[3] + ' GMT'
f.content_type = content_type
f.save() def get(self):
#获取缓存
f = cache.objects.get(name=self.url)
return (f.content, f.content_type)

最后修改urls.py

from django.conf.urls import include, url
# from django.contrib import admin
from server.views import *
urlpatterns = [
# url(r'^admin/', include(admin.site.urls)),
url('.*',home),
]

为了防止post的时候受干扰,把settings.py中的中间件去掉csrf,剩下的如图

下面启动项目,监听8000端口

把浏览器设置代理为127.0.0.1:8000

打开博客园首页,正常显示

访问人人网,由于黑名单的表中有这条规则,返回我们写的禁止页

访问爱奇艺,由于钓鱼规则中配置了将爱奇艺引导到博客园,返回的是对博客园的重定向

到此就完成了一个简单的HTTP代理服务器

基于django做HTTP代理服务器的更多相关文章

  1. 基于django做增删改查组件,分页器组件

    增删改查组件 一.Djangoadmin的启发 二.基于Djangoadmin实现数据的增删改查 分页器组件 分页器组件的介绍以及源码解读 补充:源码下载,

  2. 基于Django做权限控制

    一.权限信息初始化 二.中间件操作 三.自定义标签 补充:数据表设计,源码下载,其它

  3. 【Django】基于Django架构网站代码的目录结构

     经典的Django项目源码目录结构 Django在一个项目的目录结构划分方面缺乏必要的规范.在Django的官方文档中并没有给出大型项目的代码建议目录结构,网上的文章也是根据项目的不同结构也有适当的 ...

  4. 基于Django 的 FreeSwitch 开源GUI 管理系统 YouPBX

    YouPBX YouPBX 是一个强大 FreeSwift (电话软交换系统) 的管理GUI系统,基于Django开发,功能全面,体验友好,可以基于此项目做一个完善的IPPBX系统.呼叫中心应用等 项 ...

  5. python 全栈开发,Day95(RESTful API介绍,基于Django实现RESTful API,DRF 序列化)

    昨日内容回顾 1. rest framework serializer(序列化)的简单使用 QuerySet([ obj, obj, obj]) --> JSON格式数据 0. 安装和导入: p ...

  6. web 框架的本质及自定义web框架 模板渲染jinja2 mvc 和 mtv框架 Django框架的下载安装 基于Django实现的一个简单示例

    Django基础一之web框架的本质 本节目录 一 web框架的本质及自定义web框架 二 模板渲染JinJa2 三 MVC和MTV框架 四 Django的下载安装 五 基于Django实现的一个简单 ...

  7. 基于Django的Disqus如何支持每月80亿PV(转)

    原文:基于Django的Disqus如何支持每月80亿PV 本文由 伯乐在线 - 贱圣OMG 翻译.未经许可,禁止转载!英文出处:Matt Robenolt.欢迎加入翻译小组. 现在我们Disqus能 ...

  8. 基于Django进行简单的微信开发

    代码地址如下:http://www.demodashi.com/demo/11756.html 一.微信公众号的准备: 1. 注册 访问地址:https://mp.weixin.qq.com/ 按照提 ...

  9. 【python】-- 基于Django的杂货铺

    Django的杂货铺 此篇文章保存基于Django而实现的各种小功能示例 1.验证码 + Session 这个是在前端图片验证码的生成,再配合Session进行后端校验的功能示例 import ran ...

随机推荐

  1. layer插件

    最近在做公司的官网,其中有用到layer这款插件,以前没有接触过,不过学下来觉得好用好学.下面分享一下我的学习心得. layer是web弹出层组件.在官网下载好layer后,把他部署到你的项目文件中( ...

  2. JavaScript高级程序设计(学习)

    文档模式是:混杂模式和标准模式. 若在文档开始处没有文档类型声明,则浏览器就会开启混杂模式.这种模式在不同的浏览器下行为差异非常大,如果不使用某些hack技术,跨浏览器的行为根本就没有一致性可言. 局 ...

  3. less可以做什么?less详解!(less嵌套选择器实现纯CSS二级导航)

    前端技术众多,作为一名前端工程师,我们每接触新技术首先要懂得此技术的优势和劣势,这是最基本的.往深入了说还需要懂得技术的应用场景,配合的技术等,方便为以后架构做准备.而less作为一门CSS预处理语言 ...

  4. java学习笔记----java入门

    java基础 一.java语言跨平台原理 1.什么是跨平台? 跨平台就是一个软件可以在不同的操作系统中运行,但是不需要对其修改.换句话说,java语言编写的软件在不做修改的情况下就能在不同的系统平台上 ...

  5. Python可视化学习(1):Matplotlib的配置

    Matplotlib是一个优秀的可视化库,它提供了丰富的接口,让Python的可视化落地显得非常容易上手.本系列是本人学习python可视化的学习笔记,主要用于监督自己的学习进度,同时也希望和相关的博 ...

  6. 免费SSL证书PK付费SSL证书 花落谁家

    3月17日和18日,Google Chrome 57.0.2987.110与Mozilla Firefox 52.0.1分别上线,而这两款浏览器都出现了一个共同点:打压HTTP协议.在Firefox ...

  7. English Learn

    English Learn 一直决定好好学习英语.越来越觉得英语的重要性,解决日常问题.学习新东西.使用google时都经常碰到英文.所以觉得在blog上记录些学习英语的文章,也算是对自己的一种监督. ...

  8. IOS开发创建开发证书及发布App应用(一)——流程说明

    之前在自己做的博客网站上面发布了这个系列的文章,当时还是不错的,帮助了很多跟我一样的新手朋友,不过由于服务器出现问题,丢失了一年了,现在终于找到了,所以发到博客园给大家共享一下,也是为我自己做个参考 ...

  9. [SinGuLaRiTy] COCI 2016~2017 #5

    [SinGuLaRiTy-1012] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 最近神犇喜欢考COCI...... 测试题目 对于所有的 ...

  10. DCN路由操作

    offset */interface in/out access-list/prefix-list <1-16>                 // 修改路由偏移量   RIP偏移列表 ...